Абстрактная фабрика (Abstract factory)
Также известен как Инструментарий (Kit).
Паттерн Абстрактная Фабрика предоставляет интерфейс создания семейств взаимосвязанных или взаимозависимых объектов без указания их конкретных классов.
-
AbstractFactory - абстрактная фабрика
-
ConcreteFactory - конкретная фабрика
-
Product - абстрактный продукт
-
ConcreteProduct - конкретный продукт
-
Client - клиент
Абстрактная реализация на C# (GoF)
/// <summary>
/// MainApp startup class for Structural
/// Abstract Factory Design Pattern.
/// </summary>
internal class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
public static void Main()
{
// Abstract factory #1
AbstractFactory factory1 = new ConcreteFactory1();
Client client1 = new Client(factory1);
client1.Run();
// Abstract factory #2
AbstractFactory factory2 = new ConcreteFactory2();
Client client2 = new Client(factory2);
client2.Run();
// Wait for user input
Console.ReadKey();
}
}
/// <summary>
/// The 'AbstractFactory' abstract class
/// </summary>
internal abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA();
public abstract AbstractProductB CreateProductB();
}
/// <summary>
/// The 'ConcreteFactory1' class
/// </summary>
internal class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
}
public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
/// <summary>
/// The 'ConcreteFactory2' class
/// </summary>
internal class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA2();
}
public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
/// <summary>
/// The 'AbstractProductA' abstract class
/// </summary>
internal abstract class AbstractProductA
{
}
/// <summary>
/// The 'AbstractProductB' abstract class
/// </summary>
internal abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
}
/// <summary>
/// The 'ProductA1' class
/// </summary>
internal class ProductA1 : AbstractProductA
{
}
/// <summary>
/// The 'ProductB1' class
/// </summary>
internal class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name +
" interacts with " + a.GetType().Name);
}
}
/// <summary>
/// The 'ProductA2' class
/// </summary>
internal class ProductA2 : AbstractProductA
{
}
/// <summary>
/// The 'ProductB2' class
/// </summary>
internal class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name +
" interacts with " + a.GetType().Name);
}
}
/// <summary>
/// The 'Client' class. Interaction environment for the products.
/// </summary>
internal class Client
{
private AbstractProductA abstractProductA;
private AbstractProductB abstractProductB;
// Constructor
public Client(AbstractFactory factory)
{
abstractProductB = factory.CreateProductB();
abstractProductA = factory.CreateProductA();
}
public void Run()
{
abstractProductB.Interact(abstractProductA);
}
}
Реальная реализация на C# (GoF)
/// <summary>
/// MainApp startup class for Real-World
/// Abstract Factory Design Pattern.
/// </summary>
internal class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
public static void Main()
{
// Create and run the African animal world
ContinentFactory africa = new AfricaFactory();
AnimalWorld world = new AnimalWorld(africa);
world.RunFoodChain();
// Create and run the American animal world
ContinentFactory america = new AmericaFactory();
world = new AnimalWorld(america);
world.RunFoodChain();
// Wait for user input
Console.ReadKey();
}
}
/// <summary>
/// The 'AbstractFactory' abstract class
/// </summary>
internal abstract class ContinentFactory
{
public abstract Herbivore CreateHerbivore();
public abstract Carnivore CreateCarnivore();
}
/// <summary>
/// The 'ConcreteFactory1' class
/// </summary>
internal class AfricaFactory : ContinentFactory
{
public override Herbivore CreateHerbivore()
{
return new Wildebeest();
}
public override Carnivore CreateCarnivore()
{
return new Lion();
}
}
/// <summary>
/// The 'ConcreteFactory2' class
/// </summary>
internal class AmericaFactory : ContinentFactory
{
public override Herbivore CreateHerbivore()
{
return new Bison();
}
public override Carnivore CreateCarnivore()
{
return new Wolf();
}
}
/// <summary>
/// The 'AbstractProductA' abstract class
/// </summary>
internal abstract class Herbivore
{
}
/// <summary>
/// The 'AbstractProductB' abstract class
/// </summary>
internal abstract class Carnivore
{
public abstract void Eat(Herbivore h);
}
/// <summary>
/// The 'ProductA1' class
/// </summary>
internal class Wildebeest : Herbivore
{
}
/// <summary>
/// The 'ProductB1' class
/// </summary>
internal class Lion : Carnivore
{
public override void Eat(Herbivore h)
{
// Eat Wildebeest
Console.WriteLine(this.GetType().Name +
" eats " + h.GetType().Name);
}
}
/// <summary>
/// The 'ProductA2' class
/// </summary>
internal class Bison : Herbivore
{
}
/// <summary>
/// The 'ProductB2' class
/// </summary>
internal class Wolf : Carnivore
{
public override void Eat(Herbivore h)
{
// Eat Bison
Console.WriteLine(this.GetType().Name +
" eats " + h.GetType().Name);
}
}
/// <summary>
/// The 'Client' class
/// </summary>
internal class AnimalWorld
{
private Herbivore herbivore;
private Carnivore carnivore;
// Constructor
public AnimalWorld(ContinentFactory factory)
{
carnivore = factory.CreateCarnivore();
herbivore = factory.CreateHerbivore();
}
public void RunFoodChain()
{
carnivore.Eat(herbivore);
}
}
Улучшенная реальная реализация на C# (GoF)
/// <summary>
/// MainApp startup class for .NET optimized
/// Abstract Factory Design Pattern.
/// </summary>
internal class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
public static void Main()
{
// Create and run the African animal world
var africa = new AnimalWorld<Africa>();
africa.RunFoodChain();
// Create and run the American animal world
var america = new AnimalWorld<America>();
america.RunFoodChain();
// Wait for user input
Console.ReadKey();
}
}
/// <summary>
/// The 'AbstractFactory' interface.
/// </summary>
internal interface IContinentFactory
{
IHerbivore CreateHerbivore();
ICarnivore CreateCarnivore();
}
/// <summary>
/// The 'ConcreteFactory1' class.
/// </summary>
internal class Africa : IContinentFactory
{
public IHerbivore CreateHerbivore()
{
return new Wildebeest();
}
public ICarnivore CreateCarnivore()
{
return new Lion();
}
}
/// <summary>
/// The 'ConcreteFactory2' class.
/// </summary>
internal class America : IContinentFactory
{
public IHerbivore CreateHerbivore()
{
return new Bison();
}
public ICarnivore CreateCarnivore()
{
return new Wolf();
}
}
/// <summary>
/// The 'AbstractProductA' interface
/// </summary>
internal interface IHerbivore
{
}
/// <summary>
/// The 'AbstractProductB' interface
/// </summary>
internal interface ICarnivore
{
void Eat(IHerbivore h);
}
/// <summary>
/// The 'ProductA1' class
/// </summary>
internal class Wildebeest : IHerbivore
{
}
/// <summary>
/// The 'ProductB1' class
/// </summary>
internal class Lion : ICarnivore
{
public void Eat(IHerbivore h)
{
// Eat Wildebeest
Console.WriteLine(this.GetType().Name +
" eats " + h.GetType().Name);
}
}
/// <summary>
/// The 'ProductA2' class
/// </summary>
internal class Bison : IHerbivore
{
}
/// <summary>
/// The 'ProductB2' class
/// </summary>
internal class Wolf : ICarnivore
{
public void Eat(IHerbivore h)
{
// Eat Bison
Console.WriteLine(this.GetType().Name +
" eats " + h.GetType().Name);
}
}
/// <summary>
/// The 'Client' interface
/// </summary>
internal interface IAnimalWorld
{
void RunFoodChain();
}
/// <summary>
/// The 'Client' class
/// </summary>
internal class AnimalWorld<T> : IAnimalWorld where T : IContinentFactory, new()
{
private IHerbivore herbivore;
private ICarnivore carnivore;
private T factory;
/// <summary>
/// Contructor of Animalworld
/// </summary>
public AnimalWorld()
{
// Create new continent factory
factory = new T();
// Factory creates carnivores and herbivores
carnivore = factory.CreateCarnivore();
herbivore = factory.CreateHerbivore();
}
/// <summary>
/// Runs the foodchain: carnivores are eating herbivores.
/// </summary>
public void RunFoodChain()
{
carnivore.Eat(herbivore);
}
}
Реализация на C# (Head First)
// PizzaTestDrive test application
internal class PizzaTestDrive
{
private static void Main(string[] args)
{
PizzaStore nyStore = new NewYorkPizzaStore();
PizzaStore chStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.OrderPizza("cheese");
Console.WriteLine("Ethan ordered a " + pizza.Name + "\n");
pizza = chStore.OrderPizza("cheese");
Console.WriteLine("Joel ordered a " + pizza.Name + "\n");
pizza = nyStore.OrderPizza("clam");
Console.WriteLine("Ethan ordered a " + pizza.Name + "\n");
pizza = chStore.OrderPizza("clam");
Console.WriteLine("Joel ordered a " + pizza.Name + "\n");
pizza = nyStore.OrderPizza("pepperoni");
Console.WriteLine("Ethan ordered a " + pizza.Name + "\n");
pizza = chStore.OrderPizza("pepperoni");
Console.WriteLine("Joel ordered a " + pizza.Name + "\n");
pizza = nyStore.OrderPizza("veggie");
Console.WriteLine("Ethan ordered a " + pizza.Name + "\n");
pizza = chStore.OrderPizza("veggie");
Console.WriteLine("Joel ordered a " + pizza.Name + "\n");
// Wait for user
Console.ReadKey();
}
}
#region Ingredient Abstract Factory
public interface IPizzaIngredientFactory
{
IDough CreateDough();
ISauce CreateSauce();
ICheese CreateCheese();
IVeggies[] CreateVeggies();
IPepperoni CreatePepperoni();
IClams CreateClam();
}
public class NewYorkPizzaIngredientFactory : IPizzaIngredientFactory
{
public IDough CreateDough()
{
return new ThinCrustDough();
}
public ISauce CreateSauce()
{
return new MarinaraSauce();
}
public ICheese CreateCheese()
{
return new ReggianoCheese();
}
public IVeggies[] CreateVeggies()
{
IVeggies[] veggies = { new Garlic(),
new Onion(),
new Mushroom(),
new RedPepper() };
return veggies;
}
public IPepperoni CreatePepperoni()
{
return new SlicedPepperoni();
}
public IClams CreateClam()
{
return new FreshClams();
}
}
public class ChicagoPizzaIngredientFactory : IPizzaIngredientFactory
{
public IDough CreateDough()
{
return new ThickCrustDough();
}
public ISauce CreateSauce()
{
return new PlumTomatoSauce();
}
public ICheese CreateCheese()
{
return new MozzarellaCheese();
}
public IVeggies[] CreateVeggies()
{
IVeggies[] veggies = { new BlackOlives(),
new Spinach(),
new Eggplant() };
return veggies;
}
public IPepperoni CreatePepperoni()
{
return new SlicedPepperoni();
}
public IClams CreateClam()
{
return new FrozenClams();
}
}
#endregion Ingredient Abstract Factory
#region Pizza Stores
public abstract class PizzaStore
{
public Pizza OrderPizza(string type)
{
Pizza pizza = CreatePizza(type);
Console.WriteLine("--- Making a " + pizza.Name + " ---");
pizza.Prepare();
pizza.Bake();
pizza.Cut();
pizza.Box();
return pizza;
}
public abstract Pizza CreatePizza(string item);
}
public class NewYorkPizzaStore : PizzaStore
{
public override Pizza CreatePizza(string item)
{
Pizza pizza = null;
IPizzaIngredientFactory ingredientFactory =
new NewYorkPizzaIngredientFactory();
switch (item)
{
case "cheese":
pizza = new CheesePizza(ingredientFactory);
pizza.Name = "New York Style Cheese Pizza";
break;
case "veggie":
pizza = new VeggiePizza(ingredientFactory);
pizza.Name = "New York Style Veggie Pizza";
break;
case "clam":
pizza = new ClamPizza(ingredientFactory);
pizza.Name = "New York Style Clam Pizza";
break;
case "pepperoni":
pizza = new PepperoniPizza(ingredientFactory);
pizza.Name = "New York Style Pepperoni Pizza";
break;
}
return pizza;
}
}
public class ChicagoPizzaStore : PizzaStore
{
// Factory method implementation
public override Pizza CreatePizza(string item)
{
Pizza pizza = null;
IPizzaIngredientFactory ingredientFactory =
new ChicagoPizzaIngredientFactory();
switch (item)
{
case "cheese":
pizza = new CheesePizza(ingredientFactory);
pizza.Name = "Chicago Style Cheese Pizza";
break;
case "veggie":
pizza = new VeggiePizza(ingredientFactory);
pizza.Name = "Chicago Style Veggie Pizza";
break;
case "clam":
pizza = new ClamPizza(ingredientFactory);
pizza.Name = "Chicago Style Clam Pizza";
break;
case "pepperoni":
pizza = new PepperoniPizza(ingredientFactory);
pizza.Name = "Chicago Style Pepperoni Pizza";
break;
}
return pizza;
}
}
#endregion Pizza Stores
#region Pizzas
public abstract class Pizza
{
protected IDough dough;
protected ISauce sauce;
protected IVeggies[] veggies;
protected ICheese cheese;
protected IPepperoni pepperoni;
protected IClams clam;
private string name;
public abstract void Prepare();
public void Bake()
{
Console.WriteLine("Bake for 25 minutes at 350");
}
public virtual void Cut()
{
Console.WriteLine("Cutting the pizza into diagonal slices");
}
public void Box()
{
Console.WriteLine("Place pizza in official Pizzastore box");
}
public string Name
{
get { return name; }
set { name = value; }
}
public override string ToString()
{
StringBuilder result = new StringBuilder();
result.Append("---- " + this.Name + " ----\n");
if (dough != null)
{
result.Append(dough);
result.Append("\n");
}
if (sauce != null)
{
result.Append(sauce);
result.Append("\n");
}
if (cheese != null)
{
result.Append(cheese);
result.Append("\n");
}
if (veggies != null)
{
for (int i = 0; i < veggies.Length; i++)
{
result.Append(veggies[i]);
if (i < veggies.Length - 1)
{
result.Append(", ");
}
}
result.Append("\n");
}
if (clam != null)
{
result.Append(clam);
result.Append("\n");
}
if (pepperoni != null)
{
result.Append(pepperoni);
result.Append("\n");
}
return result.ToString();
}
}
public class ClamPizza : Pizza
{
private IPizzaIngredientFactory _ingredientFactory;
public ClamPizza(IPizzaIngredientFactory ingredientFactory)
{
this._ingredientFactory = ingredientFactory;
}
public override void Prepare()
{
Console.WriteLine("Preparing " + this.Name);
dough = _ingredientFactory.CreateDough();
sauce = _ingredientFactory.CreateSauce();
cheese = _ingredientFactory.CreateCheese();
clam = _ingredientFactory.CreateClam();
}
}
public class CheesePizza : Pizza
{
private IPizzaIngredientFactory _ingredientFactory;
public CheesePizza(IPizzaIngredientFactory ingredientFactory)
{
this._ingredientFactory = ingredientFactory;
}
public override void Prepare()
{
Console.WriteLine("Preparing " + this.Name);
dough = _ingredientFactory.CreateDough();
sauce = _ingredientFactory.CreateSauce();
cheese = _ingredientFactory.CreateCheese();
}
}
public class PepperoniPizza : Pizza
{
private IPizzaIngredientFactory _ingredientFactory;
public PepperoniPizza(IPizzaIngredientFactory ingredientFactory)
{
this._ingredientFactory = ingredientFactory;
}
public override void Prepare()
{
Console.WriteLine("Preparing " + this.Name);
dough = _ingredientFactory.CreateDough();
sauce = _ingredientFactory.CreateSauce();
cheese = _ingredientFactory.CreateCheese();
veggies = _ingredientFactory.CreateVeggies();
pepperoni = _ingredientFactory.CreatePepperoni();
}
}
public class VeggiePizza : Pizza
{
private IPizzaIngredientFactory _ingredientFactory;
public VeggiePizza(IPizzaIngredientFactory ingredientFactory)
{
this._ingredientFactory = ingredientFactory;
}
public override void Prepare()
{
Console.WriteLine("Preparing " + this.Name);
dough = _ingredientFactory.CreateDough();
sauce = _ingredientFactory.CreateSauce();
cheese = _ingredientFactory.CreateCheese();
veggies = _ingredientFactory.CreateVeggies();
}
}
#endregion Pizzas
#region Ingredients
public class ThinCrustDough : IDough
{
public override string ToString()
{
return "Thin Crust Dough";
}
}
public class ThickCrustDough : IDough
{
public override string ToString()
{
return "ThickCrust style extra thick crust dough";
}
}
public class Spinach : IVeggies
{
public override string ToString()
{
return "Spinach";
}
}
public class SlicedPepperoni : IPepperoni
{
public override string ToString()
{
return "Sliced Pepperoni";
}
}
public interface ISauce
{
string ToString();
}
public interface IDough
{
string ToString();
}
public interface IClams
{
string ToString();
}
public interface IVeggies
{
string ToString();
}
public interface ICheese
{
string ToString();
}
public interface IPepperoni
{
string ToString();
}
public class Garlic : IVeggies
{
public override string ToString()
{
return "Garlic";
}
}
public class Onion : IVeggies
{
public override string ToString()
{
return "Onion";
}
}
public class Mushroom : IVeggies
{
public override string ToString()
{
return "Mushrooms";
}
}
public class Eggplant : IVeggies
{
public override string ToString()
{
return "Eggplant";
}
}
public class BlackOlives : IVeggies
{
public override string ToString()
{
return "Black Olives";
}
}
public class RedPepper : IVeggies
{
public override string ToString()
{
return "Red Pepper";
}
}
public class PlumTomatoSauce : ISauce
{
public override string ToString()
{
return "Tomato sauce with plum tomatoes";
}
}
public class MarinaraSauce : ISauce
{
public override string ToString()
{
return "Marinara Sauce";
}
}
public class FreshClams : IClams
{
public override string ToString()
{
return "Fresh Clams from Long Island Sound";
}
}
public class FrozenClams : IClams
{
public override string ToString()
{
return "Frozen Clams from Chesapeake Bay";
}
}
public class ParmesanCheese : ICheese
{
public override string ToString()
{
return "Shredded Parmesan";
}
}
public class MozzarellaCheese : ICheese
{
public override string ToString()
{
return "Shredded Mozzarella";
}
}
public class ReggianoCheese : ICheese
{
public override string ToString()
{
return "Reggiano Cheese";
}
}
#endregion Ingredients
Реализация на JAVA
TODO