设计模式之装饰者模式
- 装饰者模式,顾名思义,就是将某个类重新装扮一下,使得它比原来更"漂亮",或者在功能上更强大,这就是装饰者模式所要达到的目的。但是作为原来的这个类的使用者还不应该感受到装饰前与装饰后有什么不同,否则就破坏了原有类的结构了,所以装饰器模式要做到对被装饰类的使用者透明,这是对装饰器模式的一个要求。
- 装饰者模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装 对象,也就是装饰来包裹真实的对象。
装饰者模式,动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
1. 装饰者模式的结构
-
如图2-27所示是一个典型的装饰者模式的类结构图。
-
在图2-27中各角色的描述如下。
- Component:抽象组件角色,定义一组抽象的接口,规定这个被装饰组件都有哪些功能。
- ConcreteComponent:实现这个抽象组件的所有可能。
- Decorator:装饰者角色,它持有一个Component对象实例的引用,定义一个与抽象组件一致的接口。
- ConcreteDecorator:具体的装饰者实现者,负责实现装饰者角色定义的功能。
2. Java I/O中的装饰者模式
-
装饰者模式的作用就是赋予被装饰的类更多的功能,在Java I/O类库中有很多不同的功能组合情况,这些不同 的功能组合都是使用装饰者模式实现的,下面以FilterInputStream为例介绍装饰者模式的使用。
-
如图2-28所示是FilterInputStream的类结构图。
-
InputStream类就是以抽象组件存在的;而FileInputStream就是具体组件,它实现了抽象组件的所有接口;FilterInputStream类无疑就是装饰角色,它实现了InputStream类的所有接口,并且持有InputStram的对象实例的引用;BufferInputStream是具体的装饰者实现者,它给InputStream类附加了功能,这个装饰者类的作用就是使得InputStream读取的数据保存在内存中,而提高读取的性能。与这个装饰者类有相似功能的还有LineNumberInputStream类,它的作用就是提高按行读取数据的功能,它们都使InputStream类增加了功能,或者提升了性能。
-
Person类
class Person {
public Person(){}
private String name;
public Person(String name) {
this.name = name;
}
public virtual void show() {
Console.WriteLine("装扮的{0}", name);
}
}
- 服饰类
class Finery : Person {
protected Person component;
//打扮
public void Decorate(Person component) {
this.component = component;
}
public override void Show() {
if (component != null) {
component.Show();
}
}
}
- 具体服饰类
class Tshirts : Finery {
public override void Show() {
Console.Write("大T恤");
base.Show();
}
}
class BigTrouser : Finery {
public override void Show() {
Console.Write("垮裤");
base.Show();
}
}
- 客户端代码
static void Main(String[] args) {
Person xc = new Person("小菜");
Console.WriteLine("\n第一种装扮:");
Sneakers pqx = new Sneakers();
BigTrouser kk = new BigTrouser();
TShirts dtx = new TShirts();
pqx.Decorate(xc); //装饰过程
kk.Decorate(pqx);
dtx.Decorate(kk);
dtx.Show();
Console.WriteLine("\n 第二种装扮:");
LeatherShoes px = new LeatherShoes();
Tie ld = new Tie();
Suit xz = new Suit();
px.Decorate(xc);
ld.Decorate(px);
xz.Decorate(ld);
xz.Show();
Console.Read();
}