-
设计原则:
类应该对扩展开放, 对修改关闭
__但是, 不大可能系统中的每个地方都遵循这个原则, 所以要在设计中最有可能改变的地方应用这一原则__
-
装饰者模式
动态将责任附加到对象上, 若要扩展功能, 装饰者提供了比继承更有弹性的替代方案
-
(1) 装饰者和被装饰对象有相同的超类型Component
(2) 每个组件Component__可以被单独使用__, 也可以被装饰者包起来使用
(3) 每个装饰者有一个内部的Component, 装饰者的行为 = 内部Component的行为 + 装饰者外层包的行为
(4) 依赖继承的话类的行为只能在编译期决定, 而利用装饰者可以运行时决定类的行为
(5) 装饰者和被装饰对象具有相同的类型, 意味着装饰者表面上也要继承超类型(如果超类型是类或抽象类的话), 但是这里的继承不是为了利用继承获得行为, 而是利用继承达到类型匹配
(6) 如果把代码写成依赖于具体的组件类型那么使用装饰者就很有可能出问题, 所以要针对抽象组件类型编程
-
Java类库中装饰器模式的典型应用 --java.io
眼花缭乱的xxxInputStream其实都是装饰器类, 见"InputStream.uml"
我们也可以自己实现一个InputStream的装饰器, 作用是将字母变成小写
public class LowerCaseInputStream extends FilterInputStream { public LowerCaseInputStream(InputStream in) { super(in); } public int read() throws IOException { int c = in.read(); return (c == -1 ? c : Character.toLowerCase((char) c)); } public int read(byte[] b, int offset, int len) throws IOException { int result = in.read(b, offset, len); for (int i = offset; i < offset + result; i++) { b[i] = (byte) Character.toLowerCase((char) b[i]); } return result; } }
装饰者可以在被装饰者的行为前面/后面加上自己的行为, 甚至将被装饰者的行为整个取代掉, 从而达到特定的目的
装饰者的问题是会出现很多小的装饰器类, 过度使用会引入复杂性(就像InputStream家族一样)