概念
装饰器模式可以动态地将一些属性、能力添加到一个对象上。若要扩展功能,装饰器提供了比继承更具有弹性的方式。
装饰器模式类图:
例子
如果大家看过变形金刚2,应该还记得电影后期擎天柱接受了一个老霸天虎(好像是吧)的翅膀等一系列零件,从而具备了飞行的能力。通过这个例子就能很好地理解装饰器模式。
首先是变形金刚的接口:
public interface Transformer{
public String show();
}
然后是擎天柱这个变形金刚的实现类:
public class OptimusPrime implements Transformer{
@Override
public String show(){
System.out.println("擎天柱");
return "擎天柱";
}
}
装饰器的超类:
public class TransformerDecorater implements Transformer{
protected Transformer transformer;
public TransformerDecorater(Transformer transformer){
this.transformer = transformer;
}
}
具体的装饰器,如翅膀:
public class WingTransformer extends TransformerDecorater{
public WingTransformer(Transformer transformer){
super(transformer);
}
@Override
public String show(){
String last = this.transformer.show() + "(飞行)";
System.out.println(last);
return last;
}
}
测试:
Transformer optimus-prime = new OptimusPrime();
optimus-prime = new WingTransformer(optimus-prime);
optimus-prime.show();
// 擎天柱
// 擎天柱(飞行)
分析
在上述例子中,OptimusPrime
类是被装饰的类,而WingTransformer
则是装饰器。
其实所谓装饰器就是带有“装饰物”的父类。以上面的例子来说,WingTransformer
就是“带有翅膀的变形金刚”,而具体这个变形金刚是谁,则需要通过传入一个Transformer
类对象来予以确定(既然是Transformer
类,那么传入实现了Transformer
的装饰器也是可以的,那就是多重修饰)。
那我们为WingTransformer
的构造函数传入了“擎天柱”的实例(optimus-prime
),那么此时的optimus-prime
就代表了“一个带有翅膀的变形金刚,而这个变形金刚是擎天柱”。
所以
Transformer optimus-prime = new OptimusPrime();
optimus-prime = new WingTransformer(optimus-prime);
就等价为
Transformer optimus-prime = new WingTransformer(new OptimusPrime());
总结
可能有人有疑问说“这跟子类有什么区别呢?”在上述的例子中,我们可以声明一个WingOptimusPrime
的子类来创建一个会飞的“擎天柱”。
当然,在只有“擎天柱”这一种变形金刚的情况下似乎没有什么区别。可是变形金刚不仅只有“擎天柱”一种,还有“大黄蜂”、“铁皮”等等。我们可以为每一种变形金刚都编写一个子类,但那样做过于麻烦。而使用装饰器则没有这个困扰。