这个模式花费了挺长时间,开始有点难理解,其实就是
定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。
设计初衷:通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的。
要点:装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为
以点咖啡为例:
我们在点咖啡的时候通常会有这样的情况:
点了不同的咖啡会有不同的价格,此时我们需要一个咖啡的基类,不同的咖啡重写基类的cost()方法来实现自己的价格,但有时候我们点咖啡的时候会需要添加一些额外的调料,这个时候价格就变了,而这些额外的调料现在又是不确定的,如果提供过多的set()和get()方法来进行调料的添加又会出现新的问题,如果后续推出茶,汽水之类的饮料时,我们从基类那里继承过来很多没用的set和get方法
所以在这里我们采用不一样的做法:以饮料为主体,然后在运行时以调料来“装饰”饮料,比如说顾客想要 加摩卡和加奶泡的深培咖啡,那么,要做的是:
1:拿一个深培咖啡对象(DarkRoast)
2:以摩卡(Mocha)对象装饰它
3:以奶泡(Whip)对象装饰它
4:调用cost()方法,并依赖委托(delegate)将调料的价钱加上去
最后在运行的时候:首先,调用最外圈装饰着Whip的cost()方法,Whip调用Mocha的cost()方法,Mocha调用DarkRoast的cost()方法,DarkRoast返回它的价钱$0.99,Mocha在DarkRoast的结果上加上自己的价钱$0.20,返回新的价钱$1.19。Whip在Mocha的返回结果上加上自己的价钱$0.10,然后返回最后结果$1.29。
装饰者模式具有以下特点:
装饰者和被装饰者对象具有相同的超类型。
你可以用一个或多个装饰者包装一个对象。
既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始的对象(被包装的)的场合,可以用装饰过的对象替代它。
装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。
对象可以在任何时候被装饰,所以在运行时动态的,不限量的用你喜欢的装饰者来装饰对象。
装饰者模式的说明:
装饰者模式动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
/*
* create by zxf 2016/2/18
* 这个是所有饮料以及调料的基类
* 饮料类
*/
public abstract class Beverage {
String description="Unknow Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
然后添加调味品装饰者基类
/*
* create by zxf 2016/2/18
* 这是所有调料的基类
* 调味品装饰
*/
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}
创建一种咖啡:
/*
* 浓缩咖啡 继承自
*/
public class Espresso extends Beverage{
public Espresso() {
description="Espresso";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 1.99;
}
}
创建以下调味品装饰类:
/*
* create by zxf 2016/2/18
* 摩卡装饰类 调味品
*/
public class Mocha extends CondimentDecorator{
private Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage=beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+", Mocha";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.20+beverage.cost();
}
}
/*
* create by zxf 2016/2/18
* 豆浆调味品 装饰者
*/
public class Soy extends CondimentDecorator{
private Beverage beverage;
public Soy(Beverage beverage) {
this.beverage=beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+", Soy";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.15+beverage.cost();
}
}
/*
* create by zxf 2016/1/18
* 奶泡装饰者
*/
public class Whip extends CondimentDecorator{
private Beverage beverage;
public Whip(Beverage beverage) {
this.beverage=beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+", Whip";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.10+beverage.cost();
}
}
然后调用如下代码:
//新点一杯浓缩咖啡
Beverage beverage=new Espresso();
beverage=new Mocha(beverage);//添加摩卡 使用摩卡装饰
beverage=new Whip(beverage);//添加奶泡 使用奶泡装饰
beverage=new Soy(beverage);//添加豆浆 使用豆浆装饰
System.out.println(beverage.getDescription()+";价钱为:"+beverage.cost());
结果如下:
Espresso, Mocha, Whip, Soy;价钱为:2.44
我们在点咖啡的时候