本质:不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
特点:不改变原类文件、不使用继承、动态扩展
实际使用:
/**
* @author jxdong
* @date 2018/5/14
*/
//原接口
public interface Do {
void doSomeThing();
}
/**
* @author jxdong
* @date 2018/5/14
*/
//接口实现类
public class RealAction implements Do{
@Override
public void doSomeThing() {
//具体实现
System.out.println("RealAction do SomeThing");
}
}
/**
* @author jxdong
* @date 2018/5/14
*/
public class Decorator implements Do {
//待装饰的对象
private Do doTarget;
public Decorator(Do doTarget) {
//将待装饰对象传入
this.doTarget = doTarget;
}
@Override
public void doSomeThing() {
doTarget.doSomeThing();
}
public void decoratorDoSomeThing()
{
System.out.println("before doSomeThing");
doSomeThing();
System.out.println("After doSomeThing");
}
}
/**
* @author jxdong
* @date 2018/5/14
*/
public class Main {
public static void main(String[] args) {
Decorator decorator=new Decorator(new RealAction());
decorator.doSomeThing();
System.out.println("------------------------------");
decorator.decoratorDoSomeThing();
}
运行结果:
RealAction do SomeThing
------------------------------
before doSomeThing
RealAction do SomeThing
After doSomeThing
提到装饰器模式,在JDK中 IO包下使用的装饰器和适配器模式
InputStream是一个抽象类,就是我们的待装饰类【接口】
FileInputSteam是inputSteam具体实现类,就是我们的待装饰对象。
在JDK中,提供了如BufferedInputStream对FileInputSteam进行装饰,扩展功能,如下:
String filePath="D:/test.txt"
InputStream inputStream = new FileInputStream(filePath);
final int len = inputStream.available();//记录一下流的长度
System.out.println("FileInputStream不支持mark和reset:" + inputStream.markSupported());
System.out.println("---------------------------------------------------------------------------------");
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);//装饰成 BufferedInputStream
System.out.println("BufferedInputStream支持mark和reset:" + bufferedInputStream.markSupported());
bufferedInputStream.mark(0);//标记一下
char c = (char) bufferedInputStream.read();
System.out.println("文件的第一个字符:" + c);
bufferedInputStream.reset();//重置
c = (char) bufferedInputStream.read();//再读
System.out.println("重置以后再读一个字符,依然会是第一个字符:" + c);
bufferedInputStream.reset();
System.out.println("---------------------------------------------------------------------------------");
可以看出,BufferedInputSteam相比InputSteam提供了mark reset方法
InputSteamReader则使用了适配器模式,将InuputSteam接口转换成Reader接口(也包含装饰器模式增强功能)
image.png
···
InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"utf-8");//先适配InputStreamReader
System.out.println("InputStreamReader有reader的功能,比如转码:" + inputStreamReader.getEncoding());
···
网友评论