装饰者模式的特点
装饰者和被装饰对象有相同的超类型。
可以用一个或多个装饰者包装一个对象。
因为装饰者和被装饰者具有相同的类型,所以任何需要原始对象的场合,可以用装饰过的对象代替。
装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。
对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。
装饰者模式的定义
装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
装饰者模式的实现
实现类图如下:
装饰者和被装饰者具有共同的超类,利用继承达到“类型匹配”,而不是利用继承获得“行为”;将装饰者和被装饰者组合时,加入新的行为。
装饰者模式的应用
java io 相关处理类
装饰者模式的缺点:在设计中加入大量的小类,如果过度使用,会让程序变得复杂。
装饰者模式的举例
下面这个例子也有助于理解 装饰的流程和作用
借鉴网友的例子(http://blog.youkuaiyun.com/jason0539/article/details/22713711)
现在需要一个汉堡,主体是鸡腿堡,可以选择添加生菜、酱、辣椒等等许多其他的配料,这种情况下就可以使用装饰者模式。
汉堡基类(被装饰者)
package decorator;
public abstract class Humburger {
protected String name ;
public String getName(){
return name;
}
public abstract double getPrice();
}
鸡腿堡类(被装饰者的初始状态,有些自己的简单装饰,相当于上面的Person)
package decorator;
public class ChickenBurger extends Humburger {
public ChickenBurger(){
name = "鸡腿堡";
}
@Override
public double getPrice() {
return 10;
}
}
配料的基类(装饰者,用来对汉堡进行多层装饰,每层装饰增加一些配料,相当于上面Decorator)
package decorator;
public abstract class Condiment extends Humburger {
public abstract String getName();
}
生菜(装饰者的第一层,相当于上面的decorator_zero)
package decorator;
public class Lettuce extends Condiment {
Humburger humburger;
public Lettuce(Humburger humburger){
this.humburger = humburger;
}
@Override
public String getName() {
return humburger.getName()+" 加生菜";
}
@Override
public double getPrice() {
return humburger.getPrice()+1.5;
}
}
辣椒(装饰者的第二层,相当于上面的decorator_first)
package decorator;
public class Chilli extends Condiment {
Humburger humburger;
public Chilli(Humburger humburger){
this.humburger = humburger;
}
@Override
public String getName() {
return humburger.getName()+" 加辣椒";
}
@Override
public double getPrice() {
return humburger.getPrice(); //辣椒是免费的哦
}
}
**测试类**
package decorator;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Humburger humburger = new ChickenBurger();
System.out.println(humburger.getName()+" 价钱:"+humburger.getPrice());
Lettuce lettuce = new Lettuce(humburger);
System.out.println(lettuce.getName()+" 价钱:"+lettuce.getPrice());
Chilli chilli = new Chilli(humburger);
System.out.println(chilli.getName()+" 价钱:"+chilli.getPrice());
Chilli chilli2 = new Chilli(lettuce);
System.out.println(chilli2.getName()+" 价钱:"+chilli2.getPrice());
}
}
输出
鸡腿堡 价钱:10.0
鸡腿堡 加生菜 价钱:11.5
鸡腿堡 加辣椒 价钱:10.0
鸡腿堡 加生菜 加辣椒 价钱:11.5