Прежде всего, мне кажется странным, что абстрактный класс PizzaFactory
содержит абстрактный общий метод CreatePizza
, который принимает параметр более конкретного типа ItalianPizzaFactory.PizzaType
.
Чтобы охватить проблему, которую я только что упомянул, и проблему, изложенную в посте, я бы предложил следующий подход.
public struct PizzaDefinition
{
public readonly string Tag;
public readonly string Name;
public readonly string Description;
public PizzaDefinition(string tag, string name, string description)
{
Tag = tag; Name = name; Description = description;
}
}
public abstract class PizzaFactory
{
public abstract IEnumerable<PizzaDefinition> GetMenu();
public abstract IPizza CreatePizza(PizzaDefinition pizzaDefinition);
}
public class ItalianPizzaFactory : PizzaFactory
{
public enum PizzaType
{
HamMushroom,
Deluxe,
Hawaiian
}
public override IEnumerable<PizzaDefinition> GetMenu()
{
return new PizzaDefinition[] {
new PizzaDefinition("hm:mushroom1,cheese3", "Ham&Mushroom 1", "blabla"),
new PizzaDefinition("hm:mushroom2,cheese1", "Ham&Mushroom 2", "blabla"),
new PizzaDefinition("dx", "Deluxe", "blabla"),
new PizzaDefinition("Hawaian:shrimps,caramel", "Hawaian", "blabla")
};
}
private PizzaType ParseTag(string tag, out object[] options){...}
public override IPizza CreatePizza(PizzaDefinition pizzaDefinition)
{
object[] options;
switch (ParseTag(pizzaDefinition.Tag, out options))
{
case PizzaType.HamMushroom:
return new HamAndMushroomPizza(options);
case PizzaType.Hawaiian:
return new HawaiianPizza();
default:
throw new ArgumentException("The pizza" + pizzaDefinition.Name + " is not on the menu.");
}
}
}
Как видите, метод ParseTag () может иметь произвольную сложность, анализируя простой текст или зашифрованное значение. Или поле Tag может быть простым int, которое отображается внутри некоторой таблицы рецептов пиццы с совершенно разными рецептами даже для слегка измененного содержания пиццы.