装饰一个装饰

时间:2011-05-27 07:56:45

标签: java design-patterns decorator

在实现了装饰器模式并编写了几个装饰器之后,我注意到API允许用户堆叠不兼容的装饰器。这是API设计者应该使用的模式的自然约束,还是我的部分错误地实现了模式?

例如,假设有一个类可以用二进制装饰器进行装饰,二进制装饰器用二进制编码数据,或者用字符串装饰器对字符串中的数据进行编码。鉴于使用了字符串修饰符,可以使用JSON或XML装饰器进一步修饰它。现在很明显,在应用了JSON装饰器之后,在它上面使用XML装饰器是不兼容的,或者如果使用了二进制装饰器,则XML / JSON装饰器是没有用的。

使用java.io包的Java示例:

InputStream is = someInputStream;
BufferedInputStream bis = new BufferedInputStream(is);
ObjectInputStream ois = new ObjectInputStream(bis);
DataInputStream dis = new DataInputStream(ois);

结果是未定义的,但API允许它。

3 个答案:

答案 0 :(得分:1)

装饰器可以轻松组合功能。组合功能是否有意义取决于API用户。

答案 1 :(得分:1)

Java的IO类似乎违反了一个或多个OO设计原则,例如Interface Segregation PrincipleLiskov Substitution Principle,并且滥用了实现继承。如果ObjectInputStream和DataInputStream不会从InputStream继承,那么它们只能拥有允许在它们上使用的那些方法。通过实现继承进行代码重用可能是造成这个问题的原因 - 可以通过支持组合而不是继承来避免它。

答案 2 :(得分:0)

这种约束强制执行不是我所知的装饰模式的一部分,但是没有理由不能这样做。它是API简单性与安全性(程序员错误)之间的权衡。