Decorator Pattern是类的动态扩展。它动态地形成一种is-a关系。
在我得到关于mixin和抽象类之间差异的this answer后,我开始怀疑是否使用了Decorator模式使我的API过于复杂。
答案 0 :(得分:13)
使用装饰器模式时,通常是封装,而不是扩展(或混合)基类。通常你这样做是因为你想使用类的功能,但是你想将调用包装起来,这样你就可以在调用之前或之后做一些额外的步骤。考虑LoggerDecorator
public class LoggerDecorator implements SomeInterface {
private SomeInterface delegate;
public void someMethod() {
LOGGER.debug("someMethod called");
delegate.someMethod();
}
}
您不希望实际公开委托,但您想要使用其功能。因此,无论你是我们mixins,扩展课程,还是装饰,都取决于你想要做什么。您是在扩展课程并为其添加新功能吗?或者你正在包装/装饰课程?
答案 1 :(得分:12)
当你在课堂上添加一些行为时,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 :(得分:3)
我不确定我是否同意Decorator在运行时扩展的说法。我知道这就是维基百科所说的,但我不认为这是准确的。我建议阅读GoF对Decorator模式的定义。它是一个动态扩展,是的,但肯定不一定是在运行时。