Один из самых популярных паттернов, позволяет создавать различные продукты, без указания классов продуктов.
Паттерн Фабричный Метод определяет интерфейс создания объекта, но позволяет субклассам выбрать класс создаваемого экземпляра. Таким образом, Фабричный Метод делегирует операцию создания экземпляра субклассам.
Давайте рассмотрим пример, который предполагает создания конвейера по изготовлению пиццы. Я не буду сильно перегружать кодом, остановимся на изготовлении одной конкретной пиццы, но с различной начинкой.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Паттерн_Фабричный_метод { public abstract class PizzaStore { public Pizza OrderPizza(string name) { Pizza pizza; pizza = CreatePizza(name); pizza.Prepare(); pizza.Bake(); pizza.Cut(); pizza.Box(); return pizza; } public abstract Pizza CreatePizza(string name); } public class ItaliaStylePizzaStore : PizzaStore { public override Pizza CreatePizza(string name) { Pizza pizza = null; switch (name) { case "сыр": return pizza = new ItaliaStyleCheesePizza(); case "пепперони": return pizza = new ItaliaStylePepperoniPizza(); case "вегетарианская": return pizza = new ItaliaStyleVeggiePizza(); default: return pizza; } } } public class ItaliaStyleCheesePizza : Pizza { public ItaliaStyleCheesePizza() { Name = "Итальянская пицца с соусом и сыром"; Dough = "Тесто на тонкой основе"; Sauce = "Специальны соус"; Console.WriteLine("Итальянская пицца с сыром"); } } public class ItaliaStylePepperoniPizza : Pizza { public ItaliaStylePepperoniPizza() { Console.WriteLine("Итальянская пицца с Пепперони"); } } public class ItaliaStyleVeggiePizza : Pizza { public ItaliaStyleVeggiePizza() { Console.WriteLine("Итальянская пицца с Вегетарианская"); } } public abstract class Pizza { public string Name { get; set; } public string Dough { get; set; } public string Sauce { get; set; } ArrayList toppings = new ArrayList(); internal void Prepare() { Console.WriteLine("Готовим пиццу"); Console.WriteLine("Готовим: " + Name); Console.WriteLine("Подбрасываем тесто: " + Dough); Console.WriteLine("Добавляем соус"); for (int i = 0; i < toppings.Count; i++) { Console.WriteLine(" " + toppings[i]); } } internal void Bake() { Console.WriteLine("Печем пиццу 25 минут"); } internal void Cut() { Console.WriteLine("Нарезаем пиццу по диагонали"); } internal void Box() { Console.WriteLine("Упаковываем пиццу в коробку"); } } public class CheesePizza : Pizza { public CheesePizza() { Console.WriteLine("-=Пицца с сыром=-"); } } public class PepperoniPizza : Pizza { public PepperoniPizza() { Console.WriteLine("-=Пицца Пепперони=-"); } } public class VeggiePizza : Pizza { public VeggiePizza() { Console.WriteLine("-=Пицца Вегетарианска=-"); } } public class SimplePizzaFactory { public Pizza CreatePizza(string name) { Pizza pizza = null; switch (name) { case "сыр": return pizza = new CheesePizza(); case "пепперони": return pizza = new PepperoniPizza(); case "вегетарианская": return pizza = new VeggiePizza(); default: return pizza; } } } class Program { static void Main(string[] args) { PizzaStore italiapizzaStore = new ItaliaStylePizzaStore(); Pizza pizza = italiapizzaStore.OrderPizza("сыр"); Console.ReadKey(); } } } |
В данном примере мы могли использовать вместо абстрактного класса пиццы, интрефес, но тогда нам надо было бы создатвать новые классы по приготовлению пиццы, потому частичная реализации сделана в абстрактном классе пиццы.