Каково различие между смешиванием и шаблоном "декоратор"?

Шаблон "декоратор" является динамическим расширением во времени выполнения классов. Это динамично формирует - отношения.

Я начал задаваться вопросом, сверхусложнял ли я свой API при помощи Шаблона "декоратор" после того, как я получил этот ответ о различии между смешиванием и абстрактным классом.

27
задан Community 23 May 2017 в 12:34
поделиться

3 ответа

Примесь подходит, когда вы добавляете поведение в свой класс. например возможность перечисления в случае типа коллекции. Вы можете смешать в своем классе столько наборов поведения, сколько захотите. Это хороший способ повторно использовать общий код; вы в основном получаете кучу методов бесплатно.

С другой стороны, декоратор - это скорее подлый перехватчик. Он предоставляет тот же открытый интерфейс, что и целевой объект, содержит целевой объект, которому он делегирует все клиентские вызовы; однако он украшает вызов некоторой предварительной и / или последующей обработкой. например если я пишу код для MyCollection и хочу, чтобы все вызовы этого типа регистрировались. Я мог бы создать новый декоратор MyCollectionWithTimeStampedLogging, унаследованный от базы ICollection, чтобы они выглядели идентично клиенту. Декоратор примет экземпляр ICollection в качестве параметра ctor и делегирует ему вызовы. например Добавление будет выглядеть так

public void Add( int item)
{
  _logger.log(String.Format( "{0} Add called with param {1}", DateTime.Now, item.ToString());
  _collection.Add(item);
  _logger.log(String.Format( "{0} Add completed with param {1}", DateTime.Now, item.ToString());
}
13
ответ дан 28 November 2019 в 05:45
поделиться

Я не уверен, что согласен с утверждением, что Decorator расширяется во время выполнения. Я знаю, что это то, что говорит Википедия, но не думаю, что это правильно. Я бы посоветовал прочитать определение шаблона Decorator от GoF. Да, это динамическое расширение, но оно не обязательно должно быть во время выполнения.

3
ответ дан 19 July 2019 в 19:28
поделиться

При использовании шаблона декоратора вы обычно инкапсулируют, а не расширяют (или смешивают) базовый класс. Часто вы делаете это, потому что хотите использовать функциональные возможности класса, но хотите обернуть вызовы в него, чтобы можно было выполнить некоторые дополнительные действия до или после вызова. Рассмотрим LoggerDecorator

public class LoggerDecorator implements SomeInterface {
      private SomeInterface delegate;
      public void someMethod() {
          LOGGER.debug("someMethod called");
          delegate.someMethod();
      }
}

. Фактически вы не хотите раскрывать делегат, но хотите использовать его функциональные возможности. Итак, используете ли вы миксины, расширяете класс или украшаете, действительно, зависит от того, что вы пытаетесь сделать. Вы расширяете класс и добавляете в него новые функции? Или вы оборачиваете / украшаете класс?

14
ответ дан 28 November 2019 в 05:45
поделиться
Другие вопросы по тегам:

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