abstract factory
This commit is contained in:
parent
8bfa03ce82
commit
0aabb39e79
|
@ -15,7 +15,8 @@
|
|||
|
||||
### Пораждающие
|
||||
|
||||
1. [Фабричный метод](factorymethod/)
|
||||
1. [Фабричный метод (Простая фабрика)](factorymethod/)
|
||||
2. [Абстрактная фабрика](abstractfactory/)
|
||||
|
||||
## Компиляция
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# Абстрактная фабрика
|
||||
|
||||
Порождающий паттерн проектирования, который позволяет создавать семейства связанных объектов, не привязываясь к конкретным классам создаваемых объектов.
|
||||
|
||||
Паттерн **Абстрактная Фабрика** предоставляет интерфейс создания семейств взаимосвязанных или взаимозависимых объектов без указания их конкретных классов.
|
||||
|
||||
## Принципы
|
||||
|
||||
- Код должен зависеть от абстракций, а не от конкретных классов
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.blackolives;
|
||||
|
||||
import abstractfactory.veggies;
|
||||
|
||||
class BlackOlives : Veggies
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Black Olives";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
module abstractfactory.cheese;
|
||||
|
||||
interface Cheese
|
||||
{
|
||||
string opBinary(string op : "~")(string s) const
|
||||
{
|
||||
return (cast(Object)this).toString() ~ s;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
module abstractfactory.clams;
|
||||
|
||||
interface Clams
|
||||
{
|
||||
string opBinary(string op : "~")(string s) const
|
||||
{
|
||||
return (cast(Object)this).toString() ~ s;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
module abstractfactory.dough;
|
||||
|
||||
interface Dough
|
||||
{
|
||||
string opBinary(string op : "~")(string s) const
|
||||
{
|
||||
return (cast(Object)this).toString() ~ s;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.eggplant;
|
||||
|
||||
import abstractfactory.veggies;
|
||||
|
||||
class Eggplant : Veggies
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Eggplant";
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.garlic;
|
||||
|
||||
import abstractfactory.veggies;
|
||||
|
||||
class Garlic : Veggies
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Garlic";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.marinarasauce;
|
||||
|
||||
import abstractfactory.sauce;
|
||||
|
||||
class MarinaraSauce : Sauce
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Marinara Sauce";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.mozzarellacheese;
|
||||
|
||||
import abstractfactory.cheese;
|
||||
|
||||
class MozzarellaCheese : Cheese
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Shredded Mozzarella";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.mushroom;
|
||||
|
||||
import abstractfactory.veggies;
|
||||
|
||||
class Mushroom : Veggies
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Mushroom";
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.onion;
|
||||
|
||||
import abstractfactory.veggies;
|
||||
|
||||
class Onion : Veggies
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Onion";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
module abstractfactory.pepperoni;
|
||||
|
||||
interface Pepperoni
|
||||
{
|
||||
string opBinary(string op : "~")(string s) const
|
||||
{
|
||||
return (cast(Object)this).toString() ~ s;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.redpepper;
|
||||
|
||||
import abstractfactory.veggies;
|
||||
|
||||
class RedPepper : Veggies
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Red Pepper";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.reggianocheese;
|
||||
|
||||
import abstractfactory.cheese;
|
||||
|
||||
class ReggianoCheese : Cheese
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Reggiano Cheese";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
module abstractfactory.sauce;
|
||||
|
||||
interface Sauce
|
||||
{
|
||||
string opBinary(string op : "~")(string s) const
|
||||
{
|
||||
return (cast(Object)this).toString() ~ s;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.slicedpepperoni;
|
||||
|
||||
import abstractfactory.pepperoni;
|
||||
|
||||
class SlicedPepperoni : Pepperoni
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Sliced Pepperoni";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module abstractfactory.spinach;
|
||||
|
||||
import abstractfactory.veggies;
|
||||
|
||||
class Spinach : Veggies
|
||||
{
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Spinach";
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
module abstractfactory.veggies;
|
||||
|
||||
interface Veggies
|
||||
{
|
||||
string opBinary(string op : "~")(string s) const
|
||||
{
|
||||
return (cast(Object)this).toString() ~ s;
|
||||
}
|
||||
}
|
|
@ -6,4 +6,4 @@
|
|||
|
||||
## Принципы
|
||||
|
||||
- По возможности использовать абстракции в коде
|
||||
- Код должен зависеть от абстракций, а не от конкретных классов
|
||||
|
|
Reference in New Issue