chapter03_装饰对象——装饰者模式

  • 设计原则:

    类应该__对扩展开放__, 对修改关闭

    但是, 不大可能系统中的每个地方都遵循这个原则, 所以要在设计中最有可能改变的地方应用这一原则

  • 装饰者模式

    __动态__将责任附加到对象上, 若要扩展功能, 装饰者提供了__比继承更有弹性__的替代方案

  • (1) 装饰者和被装饰对象有相同的__超类型Component__

    (2) 每个组件Component__可以被单独使用__, 也可以被装饰者包起来使用

    (3) 每个装饰者有一个内部的Component, 装饰者的行为 = 内部Component的行为 + 装饰者外层包的行为

    (4) 依赖继承的话类的行为只能在__编译期__决定, 而利用装饰者可以__运行时__决定类的行为

    (5) 装饰者和被装饰对象具有相同的类型, 意味着装饰者表面上也要继承超类型(如果超类型是类或抽象类的话), 但是这里的继承__不是为了利用继承获得行为, 而是利用继承达到类型匹配__

    (6) 如果把代码写成依赖于具体的组件类型那么使用装饰者就很有可能出问题, 所以要__针对抽象组件类型编程__

  • Java类库中装饰器模式的典型应用 --java.io

    (1) 眼花缭乱的xxxInputStream其实都是装饰器类, 见"InputStream.uml"

    阅读源码就可以发现,内部其实包了一个InputStream对象

      public class FilterInputStream extends InputStream {
    
          /**
           * The input stream to be filtered.
           */
          protected volatile InputStream in;
    
          ...
      }
    

    (2) 我们也可以自己实现一个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家族一样)

猜你喜欢

转载自blog.csdn.net/captxb/article/details/87899899