Паттерн декоратор как его еще называют оберткой, динамически наделяет объект новыми возможностями и является гибкой альтернативой субклассированию в области расширения функциональности.
Давайте представим проблему мы разрабатываем программную часть кофейного автомата. В начале у нас автомат умел только выдавать названия сорта кофе и готовить его, а также рассчитывал его стоимость. В автомате у нас находилось не сколько сортов кофе, соответственно нам, согласно ООП, пришлось бы создать абстрактный класс, в котором было название кофе и его стоимость, а также наследники — это сорта кофе и переопределенная стоимость каждого из них, мы потратили уйму времени на отладку и стабильность работы автомата. Через месяц нам сказали разработать возможность что бы наш автомат так же добавлял еще и сливки в кофе, начинки в виде мороженного, шоколада итд. А также предупредили что в дальнейшем возможно будут добавлены новые начинки к кофе и сами сорта кофе, а может даже и газированные напитки автомат!! Представляете какой это кошмар, если каждый раз придется все переписывать заново? Но все это можно предотвратить без особых усилий используя паттерн Декоратор.
Ниже представлена реализация паттерна Декорато на C#
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 |
using System; namespace Паттерн_Декоратор { public abstract class Beverage { public virtual string Description { get { return "Неизвестный напиток"; } } public abstract double Cost(); } public abstract class CondimentDecorator : Beverage { protected Beverage beverage; public CondimentDecorator(Beverage beverage) { this.beverage = beverage; } public override string Description { get { return beverage.Description; } } public override double Cost() { return beverage.Cost(); } } public class DarkRoast : Beverage { public DarkRoast() { } public override string Description { get => "Темный жареный кофе"; } public override double Cost() { return 80; } } public class Espresso : Beverage { public Espresso() { } public override string Description { get => "Эсперссо"; } public override double Cost() { return 140; } } public class Сhocolate : CondimentDecorator { public Сhocolate(Beverage beverage): base (beverage) {} public override double Cost() { return base.Cost() + 15; } public override string Description { get => base.Description + ", Шоколад"; } } public class IceСream : CondimentDecorator { public IceСream(Beverage beverage) : base(beverage) { } public override double Cost() { return base.Cost() + 25; } public override string Description { get => base.Description + ", Мороженное"; } } public class Whip : CondimentDecorator { public Whip(Beverage beverage) : base(beverage) { } public override double Cost() { return base.Cost() + 10; } public override string Description { get => base.Description + ", Взбитые сливки"; } } public class Client { // Клиентский код работает со всеми объектами, используя интерфейс // Beverage. Таким образом, он остаётся независимым от конкретных // классов компонентов, с которыми работает. public void PayCheck(Beverage beverage) { Console.WriteLine("Заказ: " + beverage.Description+" Цена: "+beverage.Cost()); } } class Program { static void Main(string[] args) { Client oneClient = new Client(); var darkRoastCoffe = new DarkRoast(); Сhocolate decoratorChocolate = new Сhocolate(darkRoastCoffe); Whip decoratorWhip = new Whip(decoratorChocolate); oneClient.PayCheck(decoratorWhip); Console.WriteLine(Environment.NewLine+new string('*',50)+Environment.NewLine); Client twoClient = new Client(); var espressoCoffe = new Espresso(); IceСream decoratorIceСream = new IceСream(espressoCoffe); twoClient.PayCheck(decoratorIceСream); Console.ReadKey(); } } } |
1 2 3 4 5 6 |
Заказ: Темный жареный кофе, Шоколад, Взбитые сливки Цена: 105 ************************************************** Заказ: Эсперссо, Мороженное Цена: 165 |