修饰器模式
Decorator装饰器
定义:装饰模式是在不必改变原类文件和不使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
注意其中的几点:
● 不改变原类文件
● 不使用继承
● 动态扩展
例子:
原类的父类接口
interface A{
void method();
}
原类
class oldclass implements A{
@Override
public void method(){
System.out.println("这是修饰器模式中的被修饰类中的方法、、、");
}
}
修饰类
abstract class B extends A{
protected A a;
public B(A a){
super();
this.a = a;
}
public void method(){
a.method();
}
}
具体修饰类实现
class newClass extends B{
public newClass(A a){
super();
}
public void newmethod(){
System.out.println("这是新增加的方法");
}
@Override
public void method(){
System.out.println("这里可以将之前的类进行包装");
super();
System.out.println("包装结束");
}
}
运行的截图(不要在意内容)
在IO中的使用
//文件路径
String filePath = "/Users/gongdezhe/Desktop/Test.txt";
/**
* InputStream相当于统一接口,是装饰类和被装饰类的基本类型
* FileInputStream相当于原始的待装饰的对象,为具体实现类,也是被装饰类,他本身是个具有一些功能的完整的类。
*/
InputStream inputStream = new FileInputStream(filePath);
System.out.println("FileInputStream不支持mark和reset:" + inputStream.markSupported());
System.out.println("----------------------------------");
/**
* 下面展示一种装饰器的作用BufferedInputStream
*
* BufferedInputStream是一个具体的装饰器类A
* 其定义如下:
* BufferedInputStream extends FilterInputStream
*
* FilterInputStream是是装饰类,其继承自InputStream
* 内部存在一个inputStream实例
* BufferedInputStream提供了特有的方法:
*/
//首先装饰成BufferedInputStream
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
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();
适配器
适配器在IO流中使用
在IO中适配器的使用也比较广泛
适配器角色就是InputStreamReader,
被适配的角色是InputStream类代笔的实例对象,
目标接口是Reader类。
可以看到,InputStreamReader实现了Reader接口,并且持有了InputStream的引用,这里是通过StreamDecoder类间接持有的,因为从byte到char 要经过编码。
/******************Reader类(目标类)******************/
public abstract class Reader implements Readable, Closeable {
abstract public int read(char cbuf[], int off, int len) throws IOException;
abstract public void close() throws IOException;
}
/******************InputStreamReader类(适配器类)******************/
public class InputStreamReader extends Reader {
private final StreamDecoder sd;
//持有对被适配对象的引用
public InputStreamReader(InputStream in) {
super(in);
try {
//通过StreamDecoder类间接引用被适配的对象
sd = StreamDecoder.forInputStreamReader(in, this, (String)null);
} catch (UnsupportedEncodingException e) {
// The default encoding should always be available
throw new Error(e);
}
}
//…(省略的代码)
}
/******************InputStream类(被适配类)******************/
public abstract class InputStream implements Closeable {
//代码省略
}
装饰器与适配器异同点
装饰器与适配器都有一个别名叫做 包装模式(Wrapper),它们看似都是起到包装一个类或对象的作用,但是使用它们的目的很不一一样。
适配器模式:义是要将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的。
装饰器模式:不是要改变被装饰对象的接口,而是恰恰要保持原有的接口,但是增强原有对象的功能,或者改变原有对象的处理方式而提升性能。所以这两个模式设计的目的是不同的。