mixin和装饰器模式有什么区别?

lee*_*d00 27 language-agnostic decorator mixins

Decorator模式是类的动态扩展.它动态地形成一种is-a关系.

在我得到关于mixin和抽象类之间差异的答案之后,我开始怀疑我是否通过使用Decorator模式过度复杂化我的API .

Jef*_*rey 14

使用装饰器模式时,通常是封装,而不是扩展(或混合)基类.通常你这样做是因为你想使用类的功能,但是你想将调用包装起来,这样你就可以在调用之前或之后做一些额外的步骤.考虑一下LoggerDecorator

public class LoggerDecorator implements SomeInterface {
      private SomeInterface delegate;
      public void someMethod() {
          LOGGER.debug("someMethod called");
          delegate.someMethod();
      }
}
Run Code Online (Sandbox Code Playgroud)

您不希望实际公开委托,但您想要使用其功能.因此,无论你是我们mixins,扩展课程,还是装饰,都取决于你想要做什么.您是在扩展课程并为其添加新功能吗?或者你正在包装/装饰课程?


Gis*_*shu 13

当你在课堂上添加一些行为时,mixin很合适.例如,在集合类型的情况下枚举的能力.您可以根据需要将多组行为混合到您的班级中.它是重用公共代码的好方法; 你基本上可以免费获得一堆方法.

另一方面,装饰者更像是一个偷偷摸摸的拦截器.它公开与目标对象相同的公共接口,包含一个目标对象,它委托所有客户端调用; 然而,它通过一些预处理和/或后处理来修饰调用.例如,如果我正在针对MyCollection编写代码,并且我希望记录对此类型的所有调用.我可以派生出一个新的装饰器MyCollectionWithTimeStampedLogging,它们都是从ICollection基础派生的,因此它们看起来与客户端完全相同.装饰器将ICollection的一个实例作为ctor参数并委托调用它.例如,Add会是这样的

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());
}
Run Code Online (Sandbox Code Playgroud)