Когда использовать шаблон "декоратор"?

Я осуществил бы рефакторинг код в цикле и затем сделал бы

if( ref $results eq 'ARRAY' ){
    my_sub($result) for my $result (@$results);
}else{
    my_sub($results);
}

, Конечно, я только сделал бы это, если бы код в цикле был нетривиален.

57
задан Ravindra babu 30 May 2016 в 16:45
поделиться

5 ответов

Шаблон декоратора часто используется с потоками: вы можете обернуть поток потоком, чтобы получить дополнительную функциональность. Я видел это в среде .Net - насколько мне известно, это происходит где-то еще. Мне больше всего нравится использовать GZipStream вокруг FileStream для дополнительного сжатия.

36
ответ дан 24 November 2019 в 19:22
поделиться

Шаблон декоратора используется для добавления дополнительных функций к конкретному объекту, а не к классу объектов. Легко добавить функциональность ко всему классу объектов путем создания подкласса объекта, но невозможно расширить таким образом отдельный объект. С помощью шаблона декоратора вы можете добавить функциональность к одному объекту и оставить другие, как он, неизменными.

В Java классическим примером шаблона декоратора является реализация Java I / O Streams.

FileReader       frdr = new FileReader(filename);
LineNumberReader lrdr = new LineNumberReader(frdr);

Предыдущий код создает объект читатель - lrdr - который читает из файла и отслеживает номера строк. В строке 1 создается программа чтения файлов ( frdr ), а в строке 2 добавляется отслеживание номеров строк.

На самом деле, я настоятельно рекомендую вам взглянуть на исходный код Java для классов ввода-вывода Java.

70
ответ дан 24 November 2019 в 19:22
поделиться

Недавно я использовал шаблон декоратора в веб-службе, которая использует следующий интерфейс CommandProcessor:

public Command receive(Request request);
public Response execute(Command command);
public void respond(Response response);

В основном CommandProcessor получает запрос и создает правильную команду, выполняет команду и создает соответствующий ответ и отправляет ответ. Когда я хотел добавить время и регистрировать его, я создал TimerDecorator, который использовал существующий CommandProcessor в качестве своего компонента. TimerDecorator реализует интерфейс CommandProcessor, но просто добавляет время, а затем вызывает свою цель, которая является настоящим CommandProcessor. Примерно так:

public class TimerDecorator implements CommandProcessor {
   private CommandProcessor target;
   private Timer timer;

   public TimerDecorator(CommandProcessor processor) {
      this.target = processor;
      this.timer = new Timer();
   }

   public Command receive(Request request) {
      this.timer.start();
      return this.target.receive(request);
   }

   public Response execute(Command command) {
      return this.target.execute(command);
   }

   public void respond(Response response) {
      this.target.response(response);
      this.timer.stop();
      // log timer
   }

}

Итак, настоящий CommandProcessor заключен внутри TimerDecorator, и я могу обращаться с TimerDecorator так же, как с целевым CommandProcessor, но теперь была добавлена ​​логика синхронизации.

28
ответ дан 24 November 2019 в 19:22
поделиться

Zend Framework использует декоратор для элементов формы

Дополнительная информация: http://framework.zend.com/manual/en/zend.form.decorators.html

3
ответ дан 24 November 2019 в 19:22
поделиться

The decorator is simple yet extremely powerful. It is key in achieving separation of concerns and is an essential tool for the Open Closed Principle. Take a common example of placing an order for a product:

IOrderGateway
{
    void PlaceOrder(Order order);
{

Main implementation: AmazonAffiliateOrderGateway

Possible decorators could be:

  • IncrementPerformanceCounterOrderGateway
  • QueueOrderForLaterOnTimeoutOrderGateway
  • EmailOnExceptionOrderGateway
  • InterceptTestOrderAndLogOrderGateway

A more detailed example from here illustrates a decorator that saves contacts for orders that were created using a gift card while completing the order:

class OrderWithGiftCardGateway extends OrderGatewayDecorator
{
 ...

 public function createOrder(CreateOrderRequest $order)
 {
 if ($this->containsGiftCard($order))
 {
 $this->addContactToFolder($order);
 }

 return parent::createOrder($order);
 }
}
7
ответ дан 24 November 2019 в 19:22
поделиться
Другие вопросы по тегам:

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