Подтвердить что ты не робот

В чем разница между миксином и рисунком декоратора?

Шаблон Decorator - это динамическое расширение-время выполнения классов. Он динамически формирует отношения is-a.

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

4b9b3361

Ответ 1

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

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

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());
}

Ответ 2

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

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

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

Ответ 3

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