Паттерн Компоновщик объединяет объекты в древовидные структуры для представления иерархий часть\целое. Компоновщик позволяет клиенту выполнять однородные операции сами отдельными объектами и их совокупностями.
Паттерн Компоновщик позволяет клиенту выполнять однородные операции с комбинациями и отдельными объектами.
Паттерн Компоновщик предоставляет структуру для хранения как отдельных объектов, так и комбинаций.
В реализации паттерна Компоновщик приходится искать баланс между прозрачностью, безопасностью и вашими потребностями.
Рассмотрим пример, в котором нам надо реализовать меню для интерактивного автомата в одной из кафешек.
У нас имеются отдельные классы завтрака и обеда, с набором каких-то блюд. Когда клиент подходит к автомату, он выбирает блюда для завтрака или обеда, но часто бывает такое что в обед могут входить блюда из завтрака. А также дополнятся новыми блюдами сегодняшнего дня. Представляете сложность иерархии построения такой логики программы, когда каждый день придется вносить еще какие-то правки? Вот тут и приходит к нам на помощь Паттерн Компоновщик, который поможет создать древовидное меню блюд, и выводить всю информацию о них.
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 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
using System; using System.Collections; namespace Паттерн_Компоновщик { // Базовый класс Компонент объявляет общие операции как для простых, так и // для сложных объектов структуры. public abstract class MenuComponent { public virtual void Add(MenuComponent menuComponent) { throw new NotImplementedException(); } public virtual void Remove(MenuComponent menu) { throw new NotImplementedException(); } public virtual MenuComponent GetChild(int i) { throw new NotImplementedException(); } public virtual double GetPrice() { throw new NotImplementedException(); } public virtual bool IsVegetarian() { throw new NotImplementedException(); } public virtual void Print() { throw new NotImplementedException(); } } public class MenuItem:MenuComponent { public string Name { get; } public string Description { get; } public bool Vegetarian { get; } public double Price { get; } public MenuItem(string name, string description, bool vegetarian, double price) { this.Name = name; this.Description = description; this.Vegetarian = vegetarian; this.Price = price; } public override bool IsVegetarian() { return Vegetarian; } public override void Print() { Console.Write(" "+Name); if (IsVegetarian()) { Console.Write("(v)"); } Console.WriteLine(", "+Price); Console.WriteLine(" --"+Description); } public override void Add(MenuComponent menuComponent) { throw new NotImplementedException(); } } public class Menu : MenuComponent { ArrayList menuComponents = new ArrayList(); public string Name { get; set; } public string Description { get; set; } public Menu(string name, string description) { this.Name = name; this.Description = description; } public override void Add(MenuComponent menuComponent) { menuComponents.Add(menuComponent); } public override void Remove(MenuComponent menuComponent) { menuComponents.Remove(menuComponent); } public override MenuComponent GetChild(int i) { return (MenuComponent)menuComponents[i]; } public override void Print() { Console.Write("\n"+Name); Console.WriteLine(", "+Description); Console.WriteLine("--------------------"); //Используем итератор для перебора всех компонентов объекта Меню IEnumerator iterator = menuComponents.GetEnumerator(); while (iterator.MoveNext()) { MenuComponent menuComponent = (MenuComponent)iterator.Current; menuComponent.Print(); } } } public class DinnerMenu : Menu { public DinnerMenu(string name, string description) : base(name, description) { base.Add(new MenuItem("Манная каша", "Манная каша на миндальном молоке с ванилью", true, 120)); base.Add(new MenuItem("Чечевичный суп", "Чечевичный суп с томатами", true, 150)); base.Add(new MenuItem("Суп рассольник", "Постный рассольник", true, 180)); base.Add(new MenuItem("Фаршированные перцы", "Фаршированные перцы с грибами и кабачком", true, 230)); base.Add(new MenuItem("Овощное рагу", "Овощное рагу с мясом", false, 350)); base.Add(new MenuItem("Свинина", "Свинина под лимонной заправкой", false, 550)); } } public class BreakfastMenu : Menu { public BreakfastMenu(string name, string description):base(name,description) { base.Add(new MenuItem("Блиный гурман", "Блинчики со взбитыми яцами и тостом", true, 130)); base.Add(new MenuItem("Блиный гурман", "Блинчики со взбитыми яцами и тостом", true, 130)); base.Add(new MenuItem("Обычны завтра из блинов", "Жареный блин с сосиской", true, 130)); base.Add(new MenuItem("Блины с черникой", "Блины со свежей черникой", true, 230)); base.Add(new MenuItem("Фруктовые блины", "Блины со свежей черникой и клубникой", true, 230)); } } public class Automatic { MenuComponent allMenus; public Automatic(MenuComponent allMenus) { this.allMenus = allMenus; } public void PrintMenu() { allMenus.Print(); } } class Program { static void Main(string[] args) { MenuComponent breakfastMenu = new BreakfastMenu("Меню завтрак", "Завтрак"); MenuComponent dinnerMenu = new DinnerMenu("Меню обеда", "Обед"); MenuComponent allMenus = new Menu("Все меню","Общее меню"); allMenus.Add(breakfastMenu); allMenus.Add(dinnerMenu); dinnerMenu.Add(new MenuItem("Паста", "Спагетти с соусом маринада и ломтик хлеба на закваске", true, 140)); dinnerMenu.Add(breakfastMenu); //В меню обеда так же может входить и меню завтрака dinnerMenu.Add(new MenuItem("Фрукты", "Композиция из яблок, винограда, яблок, киви.", true, 130)); Automatic automatic = new Automatic(allMenus); automatic.PrintMenu(); Console.ReadKey(); } } } |
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 |
Все меню, Общее меню -------------------- Меню завтрак, Завтрак -------------------- Блиный гурман(v), 130 --Блинчики со взбитыми яцами и тостом Блиный гурман(v), 130 --Блинчики со взбитыми яцами и тостом Обычны завтра из блинов(v), 130 --Жареный блин с сосиской Блины с черникой(v), 230 --Блины со свежей черникой Фруктовые блины(v), 230 --Блины со свежей черникой и клубникой Меню обеда, Обед -------------------- Манная каша(v), 120 --Манная каша на миндальном молоке с ванилью Чечевичный суп(v), 150 --Чечевичный суп с томатами Суп рассольник(v), 180 --Постный рассольник Фаршированные перцы(v), 230 --Фаршированные перцы с грибами и кабачком Овощное рагу, 350 --Овощное рагу с мясом Свинина, 550 --Свинина под лимонной заправкой Паста(v), 140 --Спагетти с соусом маринада и ломтик хлеба на закваске Меню завтрак, Завтрак -------------------- Блиный гурман(v), 130 --Блинчики со взбитыми яцами и тостом Блиный гурман(v), 130 --Блинчики со взбитыми яцами и тостом Обычны завтра из блинов(v), 130 --Жареный блин с сосиской Блины с черникой(v), 230 --Блины со свежей черникой Фруктовые блины(v), 230 --Блины со свежей черникой и клубникой Фрукты(v), 130 --Композиция из яблок, винограда, яблок, киви. |