装饰着模式(Decorator)
意图
动态地给一个对象添加一些额外的职责,就增加功能来说,Decorator模式相比生成子类更为灵活
适用性
1、在不影响其他对象的情况下,以动态、透明的方式给耽搁对昂添加职责
2、处理那些可以撤销的职责
3、当不能采用生成子类的方法进行扩充时,一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长,另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类
结构
Component
定义一个对象接口,可以给这些对象动态地添加职责
ConcreteComponent
定义一个对象,可以给这个对象添加一些职责
Decorator
维持一个指向Component对象的指针,并定义一个与Component接口一致的接口
ConcreteDecorator
向组件添加职责
实现
Component
package decorator;
/**
* @Author fitz.bai
* @Date 2018/8/30 14:27
*/
public interface Home {
void duty();
}
package decorator;
/**
* @Author fitz.bai
* @Date 2018/8/30 14:31
*/
public class Room implements Home {
@Override
public void duty() {
System.out.println("遮风挡雨");
}
}
Decorator
package decorator;
/**
* @Author fitz.bai
* @Date 2018/8/30 14:40
*/
public class Decorator implements Home {
private Home home;
public Decorator(Home home) {
this.home = home;
}
@Override
public void duty() {
home.duty();
}
}
ConcreteDecorator
package decorator;
/**
* @Author fitz.bai
* @Date 2018/8/30 14:29
*/
public class Kitchen extends Decorator {
public Kitchen(Home home) {
super(home);
}
@Override
public void duty() {
super.duty();
cook();
}
private void cook() {
System.out.println("做饭");
}
}
package decorator;
/**
* @Author fitz.bai
* @Date 2018/8/30 14:29
*/
public class BedRoom extends Decorator {
public BedRoom(Home home) {
super(home);
}
@Override
public void duty() {
super.duty();
havaSleep();
}
private void havaSleep() {
System.out.println("睡觉");
}
}
Client
package decorator;
/**
* @Author fitz.bai
* @Date 2018/8/30 14:27
*/
public class Client {
public static void main(String[] args) {
Home room = new Room();
room.duty();
Decorator bedRoom = new BedRoom(room);
bedRoom.duty();
Decorator kitchen = new Kitchen(room);
kitchen.duty();
}
}
/**
遮风挡雨
遮风挡雨
睡觉
遮风挡雨
做饭
*/
优点
1、比静态继承更灵活
2、避免在层次结构高层的类有太多特征
3、可以多次装饰,得到功能更为强大的对象
4、可根据需要增加新的具体构件类和具体装饰类,原有类库代码不变,符合“开闭原则”
缺点
1、会产生很多小对象,大量小对象势必会占用更多的系统资源,在一定程序上影响程序的性能。
2、装饰模式提供了一种比继承更加灵活机动的解决方案,但同时也意味着比继承更加易于出错,排错也很困难
半透明装饰器模式与全透明装饰器模式
1、半透明装饰器模式,装饰后的类未必有和抽象构件角色同样的接口方法,它可以有自己扩展的方法
2、全透明装饰器模式,装饰后的类有着和抽象构件角色同样的接口方法
全透明装饰器模式是一种比较理想主义的想法,现实中不太可能出现。
装饰器模式和适配器模式的区别
它们都是起到包装一个类或对象的作用,但是它们使用的目的不一样:
1、适配器模式:主要目的将一个接口转变成另外一个接口,达到重复使用的目的
2、装饰器模式:不改变原接口,而是在原接口上添加职责,增强原接口的功能
装饰者模式在Java中的使用
1、字节输入流InpuStream
2、字符输入流Reader
以上可以参考一下输入流的源代码,加强对Decorator的理解