Поймите “Шаблон "декоратор"” с примером реального мира

Я изучал Шаблон "декоратор", как зарегистрировано в GOF.

Помогите мне понять Шаблон "декоратор". Кто-то мог дать пример примера использования того, где это полезно в реальном мире?

163
задан ROMANIA_engineer 8 August 2017 в 22:27
поделиться

3 ответа

Шаблон декоратора выполняет единственную задачу - динамически добавлять ответственности к любому объекту.

Рассмотрим случай с пиццерией. В пиццерии продают несколько сортов пиццы, а также добавят начинки в меню. Теперь представьте себе ситуацию, когда пиццерия должна указать цены на каждую комбинацию пиццы и начинки. Даже если есть четыре основных пиццы и 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;
    }
}
222
ответ дан 23 November 2019 в 21:18
поделиться

Это простой пример динамического добавления нового поведения к существующему объекту или шаблон декоратора. Из-за природы динамических языков, таких как Javascript, этот шаблон становится частью самого языка.

 // Объект Person, который мы будем украшать возможностью записи в журнал var person = {name: "Foo", city: "Bar"}; // Функция, которая служит декоратором и динамически добавляет метод журнала к заданному объекту function MakeLoggable (object) {object.log = function (property) {console.log (this [property]); }} // Здесь динамическая ответственность передается человеку MakeLoggable (person); // Использование недавно добавленной функциональности person.log ('name'); 
32
ответ дан 23 November 2019 в 21:18
поделиться

Стоит отметить, что модель ввода-вывода Java основана на шаблоне декоратора. Размещение этого ридера поверх этого ридера поверх ... - это действительно реальный пример декоратора.

18
ответ дан 23 November 2019 в 21:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: