目录
本文以JDK中IO流源码为基础介绍。
被装饰者
/**
* Created by leboop on 2020/5/25.
*/
public abstract class MyInputStream {
public abstract int read(String content);
}
MyInputStream是被装饰者超类,具备读取各种设备的数据功能。MyFileInputStream是MyInputStream的实现类,如下:
/**
* Created by leboop on 2020/5/25.
*/
public class MyFileInputStream extends MyInputStream {
@Override
public int read(String content) {
// 模拟读取文件
int readNum = content.length();
return readNum;
}
}
它可以读取文件数据。
现在有一个需求:在读取文件内容时,仅读取文件内容的非数字部分?如何实现呢?有一种方案是创建一个新的类,继承MyFileInputStream类,然后重写read方法,在方法中新增过滤功能,这是可以的。另一种方案是:创建一个类将原来的类包裹(装饰)起来,然后在该类中取扩展功能。
装饰器
/**
* Created by leboop on 2020/5/25.
*/
public class MyFilterInputStream extends MyInputStream {
private MyInputStream in;
public MyFilterInputStream(MyInputStream in) {
this.in = in;
}
@Override
public int read(String content) {
// 扩展的功能
String s="";
if (content != null) {
s=Pattern.compile("[0-9]").matcher(content).replaceAll("");
}
return in.read(s);
}
}
为了保留和要被装饰的对象拥有相同框架的read方法,这里通过继承被装饰者超类MyFileInputStream实现。在read方法中扩展了功能。客户端代码如下:
/**
* Created by leboop on 2020/5/25.
*/
public class DecoratorMain {
public static void main(String[] args) {
MyInputStream inputStream=new MyFilterInputStream(new MyFileInputStream());
String content="12adb";
int num=inputStream.read(content);
System.out.println("文件内容长度:"+content.length());
System.out.println("实际读取的文件内容长度:"+num);
}
}
输出结果如下:
文件内容长度:5
实际读取的文件内容长度:3
装饰模式和继承
(1)装饰模式其实是对被装饰者进行包裹,具体是创建一个装饰器,将被装饰者变为成员变量;
(2)装饰器为了拥有与被装饰者待扩展功能的方法相同的框架,通过继承被装饰者的超类来实现;
(3)装饰模式和继承都可以实现上面的功能,对于继承来说,如果扩展的功能比较多,java单继承是无法实现的,就算是多继承,也会产生获得子类。