C# :: Aufgabe #325 :: Lösung #2
2 Lösungen

#325
Zoo mittels einer Factory-Methode
Fortgeschrittener - C#
von Exception
- 12.09.2020 um 16:36 Uhr
Hallo zusammen,
heute erzeugen wir einen Zoo!
Erzeugt hierfür eine Basisklasse (oder Interface) "Animal" und einige Klassen die davon erben (z.B. "Lion", "Penguin", "Crocodile", "Snake").
Als nächsten Schritt wollen wir nun eine Factory-Klasse erzeugen, die sich am "Factory-Method-Pattern" orientiert.
In dieser Klasse soll eine Methode "createAnimal" existieren, die ein "Animal" zurückgibt.
Welches "Animal" zurückgegeben wird überlassen wir vorerst dem reinen Zufall ;)
Daher kann diese Klasse auch "RandomAnimalFactory" genannt werden.
Lasst nun 200 "Animals" in den Zoo einziehen.
Wie ist die Verteilung der "Animals" einer jeden Spezies in unserem Zoo?
Es kann mit der zufälligen Erzeugung zu einem gewissen Ungleichgewicht kommen.
So fühlt sich ein einzelner Pinguin gegen 199 Löwen sicher etwas in der Unterzahl ...
Erstellt nun eine zweite Factory-Klasse "BalancedAnimalFactory".
Diese soll ebenfalls die Methode "createAnimal" enthalten.
(Macht es nun evtl. Sinn sich auch bei den Factory-Klassen über ein Interface gedanken zu machen?)
Diese Factory soll nicht mehr komplett zufällig Tiere erzeugen sondern etwas ausgeglichener.
Die dort vorhandene "createAnimal" Methode soll wie folgt funktionieren:
Angenommen wir haben vier Tier-Klassen ("Lion", "Penguin", "Crocodile", "Snake").
Wird nun ein "Lion" erzeugt, so wird für die nächsten beiden Erzeugungen kein "Lion" mehr erzeugt.
Lasst nun erneut 200 "Animals" einziehen - vielleicht in einen zweiten "Parkabschnitt" (Array)? :)
Muss sich der Pinguin noch immer Sorgen machen?
Viel Spaß!
heute erzeugen wir einen Zoo!
Erzeugt hierfür eine Basisklasse (oder Interface) "Animal" und einige Klassen die davon erben (z.B. "Lion", "Penguin", "Crocodile", "Snake").
Als nächsten Schritt wollen wir nun eine Factory-Klasse erzeugen, die sich am "Factory-Method-Pattern" orientiert.
In dieser Klasse soll eine Methode "createAnimal" existieren, die ein "Animal" zurückgibt.
Welches "Animal" zurückgegeben wird überlassen wir vorerst dem reinen Zufall ;)
Daher kann diese Klasse auch "RandomAnimalFactory" genannt werden.
Lasst nun 200 "Animals" in den Zoo einziehen.
Wie ist die Verteilung der "Animals" einer jeden Spezies in unserem Zoo?
Es kann mit der zufälligen Erzeugung zu einem gewissen Ungleichgewicht kommen.
So fühlt sich ein einzelner Pinguin gegen 199 Löwen sicher etwas in der Unterzahl ...
Erstellt nun eine zweite Factory-Klasse "BalancedAnimalFactory".
Diese soll ebenfalls die Methode "createAnimal" enthalten.
(Macht es nun evtl. Sinn sich auch bei den Factory-Klassen über ein Interface gedanken zu machen?)
Diese Factory soll nicht mehr komplett zufällig Tiere erzeugen sondern etwas ausgeglichener.
Die dort vorhandene "createAnimal" Methode soll wie folgt funktionieren:
Angenommen wir haben vier Tier-Klassen ("Lion", "Penguin", "Crocodile", "Snake").
Wird nun ein "Lion" erzeugt, so wird für die nächsten beiden Erzeugungen kein "Lion" mehr erzeugt.
Lasst nun erneut 200 "Animals" einziehen - vielleicht in einen zweiten "Parkabschnitt" (Array)? :)
Muss sich der Pinguin noch immer Sorgen machen?
Viel Spaß!
#2

von Rulli (70 Punkte)
- 29.01.2021 um 14:14 Uhr

using System; using System.Collections.Generic; using System.Linq; using System.Text; using Aufgabe325.Creators; using Aufgabe325.Products; namespace Aufgabe325.BaseClasses { public abstract class BaseFactory : IAnimalFactory { protected StringBuilder _stringBuilder = null; protected Dictionary<string, IAnimal> _animalTypes; protected List<IAnimal> _generatetAnimals = null; protected Random _random; protected BaseFactory _factory; protected BaseFactory() { _stringBuilder = new StringBuilder(); _generatetAnimals = new List<IAnimal>(); _random = new Random(); _animalTypes = new Dictionary<string, IAnimal>() { {"Lion", new Lion() }, {"Penguin", new Penguin() }, {"Crocodile", new Crocodile() }, {"Snake", new Snake() } }; } public List<IAnimal> Animals { get => _generatetAnimals; protected set => _generatetAnimals.Add(value as IAnimal); } public int Lions => _generatetAnimals.Where(x => x.GetType() == typeof(Lion)).Count(); public int Penguins => _generatetAnimals.Where(x => x.GetType() == typeof(Penguin)).Count(); public int Crocodiles => _generatetAnimals.Where(x => x.GetType() == typeof(Crocodile)).Count(); public int Snakes => _generatetAnimals.Where(x => x.GetType() == typeof(Snake)).Count(); public abstract IAnimal CreateAnimal(); public virtual string GetStatistic() { int LionsAndPenguins = Lions + Penguins; int CrocodileAndSnakes = Crocodiles + Snakes; string nameOfFactory = _factory.GetType().Name; _stringBuilder.Append($"Generated Animals by {nameOfFactory,-22} :Runs ({Animals.Count,3})\n"); _stringBuilder.AppendLine("┌──────────────────────┬─────────────────────────┐"); _stringBuilder.Append($"│ Lions : {Lions,-5}│"); _stringBuilder.Append($"\t {Lions} + {Penguins} ({LionsAndPenguins,3}) │"); _stringBuilder.Append($"\n│ Penguins : {Penguins,-5}│"); _stringBuilder.Append($"\t+ {Crocodiles} + {Snakes} ({CrocodileAndSnakes,-3}) │\n"); _stringBuilder.Append($"│ Crocodiles : {Crocodiles,-5}├─────────────────────────┤\n"); _stringBuilder.Append($"│ Snakes : {Snakes,-5}│\tAnimals ══ {LionsAndPenguins + CrocodileAndSnakes,-6}│"); _stringBuilder.AppendLine($"\n└──────────────────────┴─────────────────────────┘"); return _stringBuilder.ToString(); } } public abstract class Zoo { private List<IAnimal> _orderedAnimals = null; protected IAnimalFactory _factory = null; public Zoo() { _orderedAnimals = new List<IAnimal>(); } public IEnumerable<IAnimal> OrderedAnimals { get => _orderedAnimals; } public IAnimal OrderAnimal(string type) { var animal = GetAnimal(type); _factory.Animals.Add(animal); _orderedAnimals.Add(animal); return animal; } public string Average => AverageOfType(); public int QuantityofOrderedAnimals => _orderedAnimals.Count; protected abstract IAnimal GetAnimal(string animal); public void RandomGenerated(int runs) { _factory = new RandomAnimalFactory(); for (int i = 0; i < runs; i++) { IAnimal animal = _factory.CreateAnimal(); _orderedAnimals.Add(animal); } Console.WriteLine(_factory.GetStatistic()); } public void BalancedGenerated(int runs) { _factory = new BalancedAnimalFactory(); for (int i = 0; i < runs; i++) { IAnimal animal = _factory.CreateAnimal(); _orderedAnimals.Add(animal); } Console.WriteLine(_factory.GetStatistic()); } private string AverageOfType() { return string.Join( "\0", $"\nAnimal in List {QuantityofOrderedAnimals,7}", $"\nLions {QuantityOfArt(new Lion()),16}", $"\nPenguin {QuantityOfArt(new Penguin()),14}", $"\nCrocodiles {QuantityOfArt(new Crocodile()),11}", $"\nSnakes {QuantityOfArt(new Snake()),15}" ); } private int QuantityOfArt(IAnimal type) { return OrderedAnimals.Where(x => x.GetType() == type.GetType()).Count(); } } using System; using System.Linq; using Aufgabe325.BaseClasses; using Aufgabe325.Products; namespace Aufgabe325.Creators { public interface IRandomAnimalFactory : IAnimalFactory { } public interface IAnimalFactory { int Crocodiles { get; } int Lions { get; } int Penguins { get; } int Snakes { get; } string GetStatistic(); List<IAnimal> Animals { get; } IAnimal CreateAnimal(); } public class BalancedAnimalFactory : BaseFactory { private int _counter = 0; private IAnimal _animal = null; private string _lastAnimal = null; public BalancedAnimalFactory() : base() { _factory = this; } public override IAnimal CreateAnimal() { do { int index = _random.Next(_animalTypes.Count); _animal = _animalTypes.Values.ElementAt(index); _lastAnimal += _animal.GetType().Name.Substring(0, 1); if (_lastAnimal.First() == _lastAnimal.GetType().Name[0]) { index = _random.Next(_lastAnimal.Length - 1); } _counter++; } while (_counter < 3); _generatetAnimals.Add(_animal); return _animal; } public new void GetStatistic() { var result = base.GetStatistic(); Console.WriteLine(result); } } public class RandomAnimalFactory : BaseFactory { public RandomAnimalFactory() : base() { _factory = this; } public override IAnimal CreateAnimal() { int index = _random.Next(_animalTypes.Count); IAnimal animal = _animalTypes.Values.Reverse().ElementAt(index); _generatetAnimals.Add(animal); return animal; } public new void GetStatistic() { var result = base.GetStatistic(); Console.WriteLine(result); } } namespace Aufgabe325.Products { public interface IAnimal { string ToString(); } public class Crocodile : IAnimal { public Crocodile() { } public override string ToString() { return nameof(Crocodile); } } public class Lion : IAnimal { public Lion() { } public override string ToString() { return nameof(Lion); } } public class Penguin : IAnimal { public Penguin() {} public override string ToString() { return nameof(Penguin); } } public class Snake : IAnimal { public Snake() { } public override string ToString() { return nameof(Snake); } } } using Aufgabe325.BaseClasses; using Aufgabe325.Products; namespace Aufgabe325 { class ConcreteZoo1 : Zoo { protected override IAnimal GetAnimal(string animal) { IAnimal selectedAnimal = _factory.Animals.Find(x => x.GetType().Name == animal); return selectedAnimal; } } class Program { static void Main(string[] args) { // composition root var zoo1 = new ConcreteZoo1(); var zoo2 = new ConcreteZoo1(); int runs = 200; // run logic Console.WriteLine(nameof(zoo1) + "\n---------" + zoo1.Average + "\n---------"); Console.ReadKey(); Console.WriteLine(nameof(zoo1) + "\n---------" + "\n---------"); zoo1.BalancedGenerated(runs); Console.WriteLine(nameof(zoo1) + " " + zoo1.Average); Console.ReadKey(); Console.WriteLine(); zoo1.RandomGenerated(runs); Console.WriteLine(nameof(zoo1) + "\n---------" + zoo1.Average + "\n---------"); Console.WriteLine(nameof(zoo2) + "\n---------" + "\n---------"); Console.ReadKey(); } } } }
Kommentare:
Für diese Lösung gibt es noch keinen Kommentar
Seite 1 von 0
1