设计模式读书笔记[3]:装饰模式(Decorator)

装饰模式(Decorator):
      动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
 
将被装饰者作为装饰者的属性传入,被装饰者会提供一些功能,但通常这些功能不太能满足需求,故须在装饰者内部再根据需要提供额外的功能,被装饰者提供的功能和装饰者提供的额外功能共同完成某种需求。
同时,装饰者还可以被包装成为被装饰者,外层装饰者再根据其它需要提供额外功能。
 
ps:继承可以静态地扩展功能,装饰模式则可以动态地扩展功能。
 
装饰模式最典型的就是Java IO了:
new UpperCaseConvertReader (
    new BufferedReader(
        new InputStreamReader(
            new ByteArrayInputStream(...)
        )
    )
)

 

简单解释:

  1. 对于ByteArrayInputStream,提供读取一个byte的read()方法,返回int,但其值范围只是0~255;
  2. InputStreamReader表示,我需要的是字符,你这个不满足我的胃口,于是包装一下,提供一个返回两个byte的read()方法,虽然返回类型也是int,但返回的范围却扩大为0~65535;
  3. BufferedReader表示,我希望以行的形式返回字符串,你这一个字符一个字符的返回太蛋疼了,于是再包装一下,提供一个返回String的readLine()方法,一次返回一行;
  4. 这 时候,某开发者不淡定了,我希望返回的全部是大写,BufferedReader你这不区分大小写太不够意思了,于是自己实现一个UpperCaseConvertReader类,提供一个readUpperCaseLine()方法,对BufferedReader返回的结果再进行大写转换处理一下,然后返回。(具体实现就不写了,很简单)
===============================================================================

其实看原始的装饰模式的时候,它要求装饰者和被装饰者具有相同的调用接口,比方说上例中的返回int的read()方法,但是到BufferedReader就变化了,它提供的包装后的接口是readLine()方法(当然read()方法它也提供,但read()方法不是主要的被包装的接口),略有不同,但有谁会说,装饰者提供不同接口就不是装饰模式呢?

所以,个人理解,只要是装饰者在被装饰者的基础上,做了一些包装工作,提供一个包装后的接口,其实就是装饰模式,并没有必要一定要求装饰者装饰的一定是和被装饰者完全相同的接口。

原文地址:https://www.cnblogs.com/ini_always/p/2474176.html