Альтернативы шаблону декоратора - PullRequest
5 голосов
/ 08 августа 2009

Я считаю, что шаблон декоратора сбивает с толку. Пожалуйста, рассмотрите пример, приведенный в «Руководстве по первому шаблону проектирования».

alt text

Итак, чтобы получить DarkRoast с двойным мокко и кнутом, вы должны написать

Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);                                       
beverage2 = new Mocha(beverage2);                                       
beverage2 = new Whip(beverage2); 

Я чувствую, что в этом нет необходимости. Вот моя реализация,

interface Beverage
{
   int Cost();
}

class DarkRoast : Beverage
{
   /* .... */
}

class Mocha : Beverage
{
   /* .... */
}

class Whip : Beverage
{
   /* .... */
}

// here is the changed part
class Order
{
    List<Beverage> beverages = new List<Beverage> beverages();
    public void AddItem(Beverage b)
    {
        beverages.Add(b);
    }

    public int Cost()
    {
        int cost;
        foreach(Beverage b in beverages)
            cost += b.Cost();
    }
}

// use it like
Order order = new Order();
order.AddItem(new DarkRoast());
order.AddItem(new Mocha());
order.AddItem(new Mocha());
order.AddItem(new Whip());
int cost = order.Cost();

ИМО, оба делают то же самое. Если да, в чем здесь преимущество использования шаблона декоратора?

Есть мысли?

Ответы [ 3 ]

16 голосов
/ 08 августа 2009

Нет, они не одинаковы.

В Head First есть 1 напиток с добавлением мокко, кнута, жаркого. В вашем примере 3 напитка.
Смотрите этот код Head First. Он работает на том же экземпляре напитка

beverage2 = new Mocha(beverage2);                                       
beverage2 = new DarkRoast(beverage2);                                       
beverage2 = new Whip(beverage2);

Ваш код создает 3 напитка (что означает, что кто-то заказал 3 вещи отдельно).
В реальной жизни это не напитки, наверное. Напиток один с добавлением ароматов.

Цель декоратора - украсить. .Net имеет TextWriter и IndentedTextWriter (я думаю), который в основном берет ваш обычный текст и применяет к нему отступы. В каком-то смысле это похоже на unix pipe, если подумать.

вход -> настройки -> настраиваемый ввод -> дополнительные настройки -> дополнительные настройки.
Выход текущей операции становится входом для следующей операции.

Не знаю, хорошо ли я это объяснил.

8 голосов
/ 08 августа 2009

Весь смысл шаблона Decorator заключается в добавлении обязанностей посредством композиции объектов, а не наследования. Наследование статично, объект. Композиция динамичная и более гибкая. Возможности для украшения бесконечны. Также возможно отменить декорацию объекта во время выполнения.

1 голос
/ 08 августа 2009

Я думаю, что вы на самом деле представляете что-то совершенно другое.

В вашем примере у вас есть заказ вызова объекта, который получает напитки, а в первом примере Head они просто украшают напиток с начинками, это вызывает следующую главную проблему.

В вашем коде заказа вы можете разместить более одного напитка, если это так, и вы размещаете более одного покрытия, какое покрытие идет с каждым напитком?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...