装饰器模式是类在运行时的动态扩展。它动态地形成一个 is-a 关系。
在我得到这个关于 mixin 和抽象类之间区别的答案后,我开始怀疑我是否使用装饰器模式使我的 API 过于复杂。
装饰器模式是类在运行时的动态扩展。它动态地形成一个 is-a 关系。
在我得到这个关于 mixin 和抽象类之间区别的答案后,我开始怀疑我是否使用装饰器模式使我的 API 过于复杂。
当您向班级添加一些行为时,mixin 很合适。例如,在集合类型的情况下枚举的能力。您可以根据需要将任意多的行为集混合到您的类中。它是重用通用代码的好方法;您基本上可以免费获得一堆方法。
另一方面,装饰器更像是一个偷偷摸摸的拦截器。它公开与目标对象相同的公共接口,包含一个目标对象,它将所有客户端调用委托给该对象;然而,它通过一些预处理和/或后处理来装饰调用。例如,如果我正在针对 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());
}
使用装饰器模式时,您通常是封装,而不是扩展(或混入)基类。通常你这样做是因为你想使用类的功能,但你想包装对它的调用,这样你就可以在调用之前或之后做一些额外的步骤。考虑一个LoggerDecorator
public class LoggerDecorator implements SomeInterface {
private SomeInterface delegate;
public void someMethod() {
LOGGER.debug("someMethod called");
delegate.someMethod();
}
}
您不想实际公开委托,但您想使用它的功能。因此,您是否使用 mixins、扩展类或装饰实际上取决于您要做什么。您是否正在扩展一个类并为其添加新功能?或者你在包装/装饰班级?