设计模式3.4 装饰器模式
2018-11-30 本文已影响1人
卢卡斯哔哔哔
点击进入我的博客
装饰器模式(Decorator)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
3.4.1 装饰器结构
![](https://img.haomeiwen.com/i14623831/71a61b062d771820.png)
- 抽象构件(Component)角色:给出一个抽象结构,以规范准备接受附加责任的对象。
- 具体构件(Concrete Component)角色:定义一个要接受附加责任的类
- 装饰(Decorator)角色:持有一个构件对象的实例,并定义一个与抽象构件接口一致的接口。
- 具体装饰(Concrete Decorator)角色:负责给构件对象“贴上”附加的责任。
3.4.2 装饰器细节
使用场景
- 需要扩展一个类的功能
- 需要动态地给一个对象增加功能,这些功能可以再动态的插销
- 需要增加由一些基本功能的排列组合而产生非常大量的功能
优点
- 更加灵活:装饰模式和继承关系的目的都是要扩展对象的功能,但是装饰模式比继承更加灵活
- 多样性:通过使用不同具体装饰类及其排列组合,可以创造出不同的行为
- 动态扩展:装饰器可以动态扩展构件类
缺点
- 会产生比继承关系更多的对象
- 比继承更加容易出错
注意点
- 装饰类的接口必须与被装饰类的接口相容。
- 尽量保持抽象构件(Component)简单。
- 可以没有抽象的(Component),此时装饰器(Decorator)一般是具体构件(Concrete Component)的一个子类。
- 装饰(Decorator)和具体装饰(Concrete Decorator)可以合并。
InputStream及其子类
![](https://img.haomeiwen.com/i14623831/05a0ddf17ec8152d.png)
- 抽象构件(Component)角色:
InputStream
- 具体构件(Concrete Component)角色:
ByteArrayInputStream
、PipedInputStream
、StringBufferInputStream
等原始流处理器。 - 装饰(Decorator)角色:
FilterInputStream
- 具体装饰(Concrete Decorator)角色:
DateInputStream
、BufferedInputStream
、LineNumberInputStream
OutputStream及其子类
也用到类装饰器模式
3.4.3 例子
// Component:一个艺人
interface Artist {
void show();
}
// Concrete Component:一个歌手
class Singer implements Artist {
@Override
public void show() {
System.out.println("Let It Go");
}
}
// 装饰后的歌手:不仅会唱歌,还会讲笑话和跳舞
class SuperSinger implements Artist {
private Artist role;
public SuperSinger(Artist role) {
this.role = role;
}
@Override
public void show() {
System.out.println("Tell Jokes!");
role.show();
System.out.println("Dance!");
}
}