abstract factory

This commit is contained in:
Alexander Zhirov 2022-11-13 03:59:35 +03:00
parent 8bfa03ce82
commit 0aabb39e79
36 changed files with 688 additions and 2 deletions

View File

@ -15,7 +15,8 @@
### Пораждающие
1. [Фабричный метод](factorymethod/)
1. [Фабричный метод (Простая фабрика)](factorymethod/)
2. [Абстрактная фабрика](abstractfactory/)
## Компиляция

View File

@ -0,0 +1,9 @@
# Абстрактная фабрика
Порождающий паттерн проектирования, который позволяет создавать семейства связанных объектов, не привязываясь к конкретным классам создаваемых объектов.
Паттерн **Абстрактная Фабрика** предоставляет интерфейс создания семейств взаимосвязанных или взаимозависимых объектов без указания их конкретных классов.
## Принципы
- Код должен зависеть от абстракций, а не от конкретных классов

37
abstractfactory/app.d Normal file
View File

@ -0,0 +1,37 @@
module abstractfactory.app;
import abstractfactory.pizza;
import abstractfactory.pizzastore;
import abstractfactory.nypizzastore;
import abstractfactory.chicagopizzastore;
import std.stdio : writeln;
void main()
{
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
writeln("Ethan ordered a ", pizza);
pizza = chicagoStore.orderPizza("cheese");
writeln("Joel ordered a ", pizza);
pizza = nyStore.orderPizza("clam");
writeln("Ethan ordered a ", pizza);
pizza = chicagoStore.orderPizza("clam");
writeln("Joel ordered a ", pizza);
pizza = nyStore.orderPizza("pepperoni");
writeln("Ethan ordered a ", pizza);
pizza = chicagoStore.orderPizza("pepperoni");
writeln("Joel ordered a ", pizza);
pizza = nyStore.orderPizza("veggie");
writeln("Ethan ordered a ", pizza);
pizza = chicagoStore.orderPizza("veggie");
writeln("Joel ordered a ", pizza);
}

View File

@ -0,0 +1,11 @@
module abstractfactory.blackolives;
import abstractfactory.veggies;
class BlackOlives : Veggies
{
override string toString() const @safe pure nothrow
{
return "Black Olives";
}
}

9
abstractfactory/cheese.d Normal file
View File

@ -0,0 +1,9 @@
module abstractfactory.cheese;
interface Cheese
{
string opBinary(string op : "~")(string s) const
{
return (cast(Object)this).toString() ~ s;
}
}

View File

@ -0,0 +1,23 @@
module abstractfactory.cheesepizza;
import abstractfactory.pizza;
import abstractfactory.pizzaingredientfactory;
import std.stdio : writeln;
class CheesePizza : Pizza
{
PizzaIngredientFactory ingredientFactory;
this(PizzaIngredientFactory ingredientFactory)
{
this.ingredientFactory = ingredientFactory;
}
override void prepare()
{
writeln("Preparing ", name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
}
}

View File

@ -0,0 +1,51 @@
module abstractfactory.chicagopizzaingredientfactory;
import abstractfactory.pizzaingredientfactory;
import abstractfactory.dough;
import abstractfactory.thincrustdough;
import abstractfactory.sauce;
import abstractfactory.plumtomatosauce;
import abstractfactory.cheese;
import abstractfactory.mozzarellacheese;
import abstractfactory.veggies;
import abstractfactory.blackolives;
import abstractfactory.spinach;
import abstractfactory.eggplant;
import abstractfactory.pepperoni;
import abstractfactory.slicedpepperoni;
import abstractfactory.clams;
import abstractfactory.frozenclams;
class ChicagoPizzaIngredientFactory : PizzaIngredientFactory
{
override Dough createDough()
{
return new ThinCrustDough();
}
override Sauce createSauce()
{
return new PlumTomatoSauce();
}
override Cheese createCheese()
{
return new MozzarellaCheese();
}
override Veggies[] createVeggies()
{
Veggies[] veggies = cast(Veggies[])[ new BlackOlives(), new Spinach(), new Eggplant() ];
return veggies;
}
override Pepperoni createPepperoni()
{
return new SlicedPepperoni();
}
override Clams createClam()
{
return new FrozenClams();
}
}

View File

@ -0,0 +1,43 @@
module abstractfactory.chicagopizzastore;
import abstractfactory.pizza;
import abstractfactory.pizzastore;
import abstractfactory.pizzaingredientfactory;
import abstractfactory.chicagopizzaingredientfactory;
import abstractfactory.cheesepizza;
import abstractfactory.veggiepizza;
import abstractfactory.clampizza;
import abstractfactory.pepperonipizza;
class ChicagoPizzaStore : PizzaStore
{
protected:
override Pizza createPizza(string item)
{
Pizza pizza;
PizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory();
if (item == "cheese")
{
pizza = new CheesePizza(ingredientFactory);
pizza.setName("Chicago Style Cheese Pizza");
}
else if (item == "veggie")
{
pizza = new VeggiePizza(ingredientFactory);
pizza.setName("Chicago Style Veggie Pizza");
}
else if (item == "clam")
{
pizza = new ClamPizza(ingredientFactory);
pizza.setName("Chicago Style Clam Pizza");
}
else if (item == "pepperoni")
{
pizza = new PepperoniPizza(ingredientFactory);
pizza.setName("Chicago Style Pepperoni Pizza");
}
return pizza;
}
}

View File

@ -0,0 +1,24 @@
module abstractfactory.clampizza;
import abstractfactory.pizza;
import abstractfactory.pizzaingredientfactory;
import std.stdio : writeln;
class ClamPizza : Pizza
{
PizzaIngredientFactory ingredientFactory;
this(PizzaIngredientFactory ingredientFactory)
{
this.ingredientFactory = ingredientFactory;
}
override void prepare()
{
writeln("Preparing ", name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
clams = ingredientFactory.createClam();
}
}

9
abstractfactory/clams.d Normal file
View File

@ -0,0 +1,9 @@
module abstractfactory.clams;
interface Clams
{
string opBinary(string op : "~")(string s) const
{
return (cast(Object)this).toString() ~ s;
}
}

9
abstractfactory/dough.d Normal file
View File

@ -0,0 +1,9 @@
module abstractfactory.dough;
interface Dough
{
string opBinary(string op : "~")(string s) const
{
return (cast(Object)this).toString() ~ s;
}
}

View File

@ -0,0 +1,11 @@
module abstractfactory.eggplant;
import abstractfactory.veggies;
class Eggplant : Veggies
{
override string toString() const @safe pure nothrow
{
return "Eggplant";
}
}

View File

@ -0,0 +1,11 @@
module abstractfactory.freshclams;
import abstractfactory.clams;
class FreshClams : Clams
{
override string toString() const @safe pure nothrow
{
return "Fresh Clams from Long Island Sound";
}
}

View File

@ -0,0 +1,11 @@
module abstractfactory.frozenclams;
import abstractfactory.clams;
class FrozenClams : Clams
{
override string toString() const @safe pure nothrow
{
return "Frozen Clams from Chesapeake Bay";
}
}

11
abstractfactory/garlic.d Normal file
View File

@ -0,0 +1,11 @@
module abstractfactory.garlic;
import abstractfactory.veggies;
class Garlic : Veggies
{
override string toString() const @safe pure nothrow
{
return "Garlic";
}
}

View File

@ -0,0 +1,11 @@
module abstractfactory.marinarasauce;
import abstractfactory.sauce;
class MarinaraSauce : Sauce
{
override string toString() const @safe pure nothrow
{
return "Marinara Sauce";
}
}

View File

@ -0,0 +1,11 @@
module abstractfactory.mozzarellacheese;
import abstractfactory.cheese;
class MozzarellaCheese : Cheese
{
override string toString() const @safe pure nothrow
{
return "Shredded Mozzarella";
}
}

View File

@ -0,0 +1,11 @@
module abstractfactory.mushroom;
import abstractfactory.veggies;
class Mushroom : Veggies
{
override string toString() const @safe pure nothrow
{
return "Mushroom";
}
}

View File

@ -0,0 +1,52 @@
module abstractfactory.nypizzaingredientfactory;
import abstractfactory.pizzaingredientfactory;
import abstractfactory.dough;
import abstractfactory.thincrustdough;
import abstractfactory.sauce;
import abstractfactory.marinarasauce;
import abstractfactory.cheese;
import abstractfactory.reggianocheese;
import abstractfactory.veggies;
import abstractfactory.garlic;
import abstractfactory.onion;
import abstractfactory.mushroom;
import abstractfactory.redpepper;
import abstractfactory.pepperoni;
import abstractfactory.slicedpepperoni;
import abstractfactory.clams;
import abstractfactory.freshclams;
class NYPizzaIngredientFactory : PizzaIngredientFactory
{
override Dough createDough()
{
return new ThinCrustDough();
}
override Sauce createSauce()
{
return new MarinaraSauce();
}
override Cheese createCheese()
{
return new ReggianoCheese();
}
override Veggies[] createVeggies()
{
Veggies[] veggies = cast(Veggies[])[ new Garlic(), new Onion(), new Mushroom(), new RedPepper() ];
return veggies;
}
override Pepperoni createPepperoni()
{
return new SlicedPepperoni();
}
override Clams createClam()
{
return new FreshClams();
}
}

View File

@ -0,0 +1,43 @@
module abstractfactory.nypizzastore;
import abstractfactory.pizza;
import abstractfactory.pizzastore;
import abstractfactory.pizzaingredientfactory;
import abstractfactory.nypizzaingredientfactory;
import abstractfactory.cheesepizza;
import abstractfactory.veggiepizza;
import abstractfactory.clampizza;
import abstractfactory.pepperonipizza;
class NYPizzaStore : PizzaStore
{
protected:
override Pizza createPizza(string item)
{
Pizza pizza;
PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
if (item == "cheese")
{
pizza = new CheesePizza(ingredientFactory);
pizza.setName("New York Style Cheese Pizza");
}
else if (item == "veggie")
{
pizza = new VeggiePizza(ingredientFactory);
pizza.setName("New York Style Veggie Pizza");
}
else if (item == "clam")
{
pizza = new ClamPizza(ingredientFactory);
pizza.setName("New York Style Clam Pizza");
}
else if (item == "pepperoni")
{
pizza = new PepperoniPizza(ingredientFactory);
pizza.setName("New York Style Pepperoni Pizza");
}
return pizza;
}
}

11
abstractfactory/onion.d Normal file
View File

@ -0,0 +1,11 @@
module abstractfactory.onion;
import abstractfactory.veggies;
class Onion : Veggies
{
override string toString() const @safe pure nothrow
{
return "Onion";
}
}

View File

@ -0,0 +1,9 @@
module abstractfactory.pepperoni;
interface Pepperoni
{
string opBinary(string op : "~")(string s) const
{
return (cast(Object)this).toString() ~ s;
}
}

View File

@ -0,0 +1,25 @@
module abstractfactory.pepperonipizza;
import abstractfactory.pizza;
import abstractfactory.pizzaingredientfactory;
import std.stdio : writeln;
class PepperoniPizza : Pizza
{
PizzaIngredientFactory ingredientFactory;
this(PizzaIngredientFactory ingredientFactory)
{
this.ingredientFactory = ingredientFactory;
}
override void prepare()
{
writeln("Preparing ", name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
veggies = ingredientFactory.createVeggies();
pepperoni = ingredientFactory.createPepperoni();
}
}

88
abstractfactory/pizza.d Normal file
View File

@ -0,0 +1,88 @@
module abstractfactory.pizza;
import abstractfactory.dough;
import abstractfactory.sauce;
import abstractfactory.veggies;
import abstractfactory.cheese;
import abstractfactory.pepperoni;
import abstractfactory.clams;
import std.stdio : writeln;
import std.conv : to;
abstract class Pizza
{
protected:
string name;
Dough dough;
Sauce sauce;
Veggies[] veggies;
Cheese cheese;
Pepperoni pepperoni;
Clams clams;
public:
void prepare();
void bake()
{
writeln("Bake for 25 minutes at 350");
}
void cut()
{
writeln("Cut the pizza into diagonal slices");
}
void box()
{
writeln("Place pizza in official PizzaStore box");
}
void setName(string name)
{
this.name = name;
}
string getName()
{
return name;
}
override string toString() const
{
string s;
s ~= "---- " ~ name ~ " ----\n";
if (dough !is null)
{
s ~= dough ~ "\n";
}
if (sauce !is null)
{
s ~= sauce ~ "\n";
}
if (cheese !is null)
{
s ~= cheese ~ "\n";
}
if (veggies.length)
{
foreach (key, val; veggies)
{
s ~= val.to!string;
if (key + 1 < veggies.length)
{
s ~= ", ";
}
}
}
if (clams !is null)
{
s ~= clams ~ "\n";
}
if (pepperoni !is null)
{
s ~= pepperoni ~ "\n";
}
return s;
}
}

View File

@ -0,0 +1,18 @@
module abstractfactory.pizzaingredientfactory;
import abstractfactory.dough;
import abstractfactory.sauce;
import abstractfactory.cheese;
import abstractfactory.veggies;
import abstractfactory.pepperoni;
import abstractfactory.clams;
interface PizzaIngredientFactory
{
Dough createDough();
Sauce createSauce();
Cheese createCheese();
Veggies[] createVeggies();
Pepperoni createPepperoni();
Clams createClam();
}

View File

@ -0,0 +1,24 @@
module abstractfactory.pizzastore;
import abstractfactory.pizza;
import std.stdio : writeln;
abstract class PizzaStore
{
protected:
Pizza createPizza(string item);
public:
Pizza orderPizza(string type)
{
Pizza pizza = createPizza(type);
writeln("--- Making a " ~ pizza.getName() ~ " ---");
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}

View File

@ -0,0 +1,11 @@
module abstractfactory.plumtomatosauce;
import abstractfactory.sauce;
class PlumTomatoSauce : Sauce
{
override string toString() const @safe pure nothrow
{
return "Tomato sauce with plum tomatoes";
}
}

View File

@ -0,0 +1,11 @@
module abstractfactory.redpepper;
import abstractfactory.veggies;
class RedPepper : Veggies
{
override string toString() const @safe pure nothrow
{
return "Red Pepper";
}
}

View File

@ -0,0 +1,11 @@
module abstractfactory.reggianocheese;
import abstractfactory.cheese;
class ReggianoCheese : Cheese
{
override string toString() const @safe pure nothrow
{
return "Reggiano Cheese";
}
}

9
abstractfactory/sauce.d Normal file
View File

@ -0,0 +1,9 @@
module abstractfactory.sauce;
interface Sauce
{
string opBinary(string op : "~")(string s) const
{
return (cast(Object)this).toString() ~ s;
}
}

View File

@ -0,0 +1,11 @@
module abstractfactory.slicedpepperoni;
import abstractfactory.pepperoni;
class SlicedPepperoni : Pepperoni
{
override string toString() const @safe pure nothrow
{
return "Sliced Pepperoni";
}
}

11
abstractfactory/spinach.d Normal file
View File

@ -0,0 +1,11 @@
module abstractfactory.spinach;
import abstractfactory.veggies;
class Spinach : Veggies
{
override string toString() const @safe pure nothrow
{
return "Spinach";
}
}

View File

@ -0,0 +1,16 @@
module abstractfactory.thincrustdough;
import abstractfactory.dough;
class ThinCrustDough : Dough
{
override string toString() const @safe pure nothrow
{
return "Thin Crust Dough";
}
string opBinary(string op : "~")(string s)
{
return (cast(Object)this).toString() ~ s;
}
}

View File

@ -0,0 +1,24 @@
module abstractfactory.veggiepizza;
import abstractfactory.pizza;
import abstractfactory.pizzaingredientfactory;
import std.stdio : writeln;
class VeggiePizza : Pizza
{
PizzaIngredientFactory ingredientFactory;
this(PizzaIngredientFactory ingredientFactory)
{
this.ingredientFactory = ingredientFactory;
}
override void prepare()
{
writeln("Preparing ", name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
veggies = ingredientFactory.createVeggies();
}
}

View File

@ -0,0 +1,9 @@
module abstractfactory.veggies;
interface Veggies
{
string opBinary(string op : "~")(string s) const
{
return (cast(Object)this).toString() ~ s;
}
}

View File

@ -6,4 +6,4 @@
## Принципы
- По возможности использовать абстракции в коде
- Код должен зависеть от абстракций, а не от конкретных классов