有时我们希望给某个对象而不是整个类添加一些功能。例如:一个图形用户界面工具箱允许我们对任意一个用户界面组件添加一些新的特性,如增加一个边框;或者增加一些行为,如窗口的滚动。
一种较为灵活的方式是将组件嵌入另一个对象中,由这个对象来添加边框。我们称这个嵌入的对象为装饰器(Decorator)。这个装饰与它所装饰的组件接口 一致,因此它对使用该组件的客户透明。它将客户请求转发给该组件,并且可 能在转发前后执行一些额外的动作。这种透明性使得我们可以递归嵌套多个装饰,从而可以添加任意多的功能。
装饰模式(Decorator Pattern):动态地给一个对象增加一些额外的职责 (Responsibility),就增加对象功能来说,装饰模式比生成子类实现 更为灵活。其别名为包装器(Wrapper)。装饰模式是一种对象结构型模 式。
参与者
Component:组件
ConcreteComponent:具体组件
Decorator:抽象装饰类
ConcreteDecorator:具体装饰类
实例:人的外观由人和服装组成
package design;
public abstract class Appearance {
public abstract void Show();
}
public class Person extends Appearance{
private String name;
public Person (String name) {
this.name = name;
}
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.println("装备"+name);
}
}
public class Finery extends Appearance {
private Appearance component;
public void Decorate(Appearance component) {
this.component = component;
}
@Override
public void Show() {
// TODO Auto-generated method stub
if(component != null) {
component.Show();
}
}
}
public class Jeans extends Finery {
@Override
public void Show() {
super.Show();
System.out.println("Jeans");
}
}
public class Sneakers extends Finery{
@Override
public void Show() {
// TODO Auto-generated method stub
super.Show();
System.out.println("Sneakers");
}
}
public class TShirts extends Finery{
@Override
public void Show() {
// TODO Auto-generated method stub
super.Show();
System.out.println("TShirts");
}
}
public class Test {
public static void main(String[] args) {
Person xc = new Person("阿三");
System.out.println("first");
Sneakers qx = new Sneakers();
Jeans nzk = new Jeans();
TShirts tx = new TShirts();
tx.Decorate(xc);
nzk.Decorate(tx);
qx.Decorate(nzk);
qx.Show();
}
}
解释:在测试函数中各个字段对应的数据含义
tx.Decorate(xc); Appearance由 xc(人)和tx(T恤)组成
nzk.Decorate(tx); Appearance由tx(由上述xc和T恤组成)和Jeans组成
qx.Decorate(nzk); Appearance由qx(由tx组成)和Sneakers组成
相当于每次都由一个pernson和一件衣服构成新的外观,然后递归调用返回构造外观。