设计模式-装饰者模式
定义
创建一个类,包装原始类,从而在新类中提升原来的功能。
作用
在不改变原有类的基础上,动态地扩展一个类的功能。
例如:IO流中的基础流和缓冲流就是典型的装饰模式
实现步骤
- 定义父类,如MyInputStream(抽象父类)
- 定义原始类,继承父类,定义功能,如MyFileInputStream(实现子类,读写性能较差)
- 定义装饰类,继承父类,包装原始类,增强功能。如MyBufferedInputStream(装饰子类,装饰类,读写性能高)
- 测试类
实战:模拟FileInputStream和BufferedInputStream
//1.这是自定义的字节输入流的父类,有只读一个字节和读一个字节数组的功能
public abstract class MyInputStream {
public abstract int read();
public abstract int read(byte[] bys);
}
/2.根据需求定义的原始文件字节输入流,继承父类,属于被强化的基础流
public class MyFileInputStream extends MyInputStream{
@Override
public int read() {
//模拟只读一个字节(伪代码)
//返回一个国定的字节a
return 97;
}
@Override
public int read(byte[] bys) {
//模拟只读一个字节数组(伪代码)
bys[0] = 97;
bys[1] = 98;
bys[2] = 99;
return 3;
}
}
import java.io.BufferedInputStream;
//3.装饰类要去强化基础流,需要继承被强化的类的父类(MyFileInputStream)
public class MyBufferedInputStream extends MyInputStream{
//装饰类,装饰类和被强化的原始类具备了同样的两个功能
//利用构造器,传入原始类
MyFileInputStream mfis;
//创建构造方法
public MyBufferedInputStream(MyFileInputStream mfis){
this.mfis = mfis;
}
@Override
public int read() {
//开始强化基础流的功能,模拟一下强化功能(伪代码)
System.out.println("从缓冲数组中读取一个字节,强化了功能!");
//调用原始类功能
int data = mfis.read();
return data;
}
@Override
public int read(byte[] bys) {
//强化基础流的读取一个字节数组的功能,模拟(伪代码)
System.out.println("从缓冲数组中读取一个字节数组,强化了功能!");
//调用原始类的功能
int len = mfis.read(bys);
return len;
}
}
import java.io.FileInputStream;
public class Demo01 {
public static void main(String[] args) {
//别人写了一个基础的字节输入流:MyFileInputStream
MyFileInputStream mfis = new MyFileInputStream();
//读取一个字节
int data = mfis.read();
System.out.println((char)data);
//读取一个字节数组
byte[] bys = new byte[1024];
int len = mfis.read(bys);
//开始解码
String s = new String(bys, 0, len);
System.out.println(s);
System.out.println("-----------");
//同事代码太垃圾,改善同事代码
//创建缓冲字节输入流对象
MyBufferedInputStream mbis = new MyBufferedInputStream(mfis);
//读取一个字节
data = mbis.read();
System.out.println((char)data);
//读取一个字节数组
bys = new byte[1024];
len = mbis.read(bys);
//开始解码
s = new String(bys, 0, len);
System.out.println(s);
}
}