【问题标题】:Decorate a decorator装饰一个装饰器
【发布时间】:2011-09-03 05:04:26
【问题描述】:

在实现了装饰器模式并编写了几个装饰器后,我注意到 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 允许。

【问题讨论】:

  • 为什么不能根据传递给编码方法的参数或单独的方法调用本身,以任何可用的格式对类进行编码?为什么用 JSON 装饰器装饰一个类会使其与 XML 装饰器不兼容?
  • 好点。可以,但在我的情况下,这将是一个编程开销。

标签: java design-patterns decorator


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2017-11-16
        • 1970-01-01
        • 1970-01-01
        • 2015-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-01
        相关资源
        最近更新 更多