您的位置:首页 > 其它

装饰着模式

2016-02-18 17:42 162 查看
以点咖啡为例:

我们在点咖啡的时候通常会有这样的情况:

点了不同的咖啡会有不同的价格,此时我们需要一个咖啡的基类,不同的咖啡重写基类的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 xuefu 2016/2/18

* 这个是所有饮料以及调料的基类

* 饮料类

*/

public abstract class Beverage {

String description="Unknow Beverage";

public String getDescription(){

return description;

}

public abstract double cost();

}

然后添加调味品装饰者基类

/*

* create by xuefu 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 xuefu 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 xuefu 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 xuefu 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

我们在点咖啡的时候
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: