Я изучал Шаблон "декоратор", как зарегистрировано в GOF.
Помогите мне понять Шаблон "декоратор". Кто-то мог дать пример примера использования того, где это полезно в реальном мире?
Шаблон декоратора выполняет единственную задачу - динамически добавлять ответственности к любому объекту.
Рассмотрим случай с пиццерией. В пиццерии продают несколько сортов пиццы, а также добавят начинки в меню. Теперь представьте себе ситуацию, когда пиццерия должна указать цены на каждую комбинацию пиццы и начинки. Даже если есть четыре основных пиццы и 8 разных начинок, приложение сошло бы с ума, поддерживая все эти конкретные комбинации пиццы и начинки.
А вот и шаблон декоратора.
В соответствии с шаблоном декоратора вы будете реализовывать начинки, поскольку декораторы и пиццы будут украшать их декораторами. Практически каждый покупатель захочет начинку по своему желанию, и окончательная сумма счета будет складываться из базовой пиццы и дополнительно заказанной начинки. Каждый декоратор должен знать о пицце, которую он украшает, и ее цене. Метод GetPrice () объекта Topping вернет совокупную цену как пиццы, так и начинки.
Вот пример кода с объяснением выше.
public abstract class BasePizza
{
protected double myPrice;
public virtual double GetPrice()
{
return this.myPrice;
}
}
public abstract class ToppingsDecorator : BasePizza
{
protected BasePizza pizza;
public ToppingsDecorator(BasePizza pizzaToDecorate)
{
this.pizza = pizzaToDecorate;
}
public override double GetPrice()
{
return (this.pizza.GetPrice() + this.myPrice);
}
}
class Program
{
[STAThread]
static void Main()
{
//Client-code
Margherita pizza = new Margherita();
Console.WriteLine("Plain Margherita: " + pizza.GetPrice().ToString());
ExtraCheeseTopping moreCheese = new ExtraCheeseTopping(pizza);
ExtraCheeseTopping someMoreCheese = new ExtraCheeseTopping(moreCheese);
Console.WriteLine("Plain Margherita with double extra cheese: " + someMoreCheese.GetPrice().ToString());
MushroomTopping moreMushroom = new MushroomTopping(someMoreCheese);
Console.WriteLine("Plain Margherita with double extra cheese with mushroom: " + moreMushroom.GetPrice().ToString());
JalapenoTopping moreJalapeno = new JalapenoTopping(moreMushroom);
Console.WriteLine("Plain Margherita with double extra cheese with mushroom with Jalapeno: " + moreJalapeno.GetPrice().ToString());
Console.ReadLine();
}
}
public class Margherita : BasePizza
{
public Margherita()
{
this.myPrice = 6.99;
}
}
public class Gourmet : BasePizza
{
public Gourmet()
{
this.myPrice = 7.49;
}
}
public class ExtraCheeseTopping : ToppingsDecorator
{
public ExtraCheeseTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 0.99;
}
}
public class MushroomTopping : ToppingsDecorator
{
public MushroomTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 1.49;
}
}
public class JalapenoTopping : ToppingsDecorator
{
public JalapenoTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 1.49;
}
}
Это простой пример динамического добавления нового поведения к существующему объекту или шаблон декоратора. Из-за природы динамических языков, таких как Javascript, этот шаблон становится частью самого языка.
// Объект Person, который мы будем украшать возможностью записи в журнал var person = {name: "Foo", city: "Bar"}; // Функция, которая служит декоратором и динамически добавляет метод журнала к заданному объекту function MakeLoggable (object) {object.log = function (property) {console.log (this [property]); }} // Здесь динамическая ответственность передается человеку MakeLoggable (person); // Использование недавно добавленной функциональности person.log ('name');
Стоит отметить, что модель ввода-вывода Java основана на шаблоне декоратора. Размещение этого ридера поверх этого ридера поверх ... - это действительно реальный пример декоратора.