装饰着模式
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
我们在点咖啡的时候
我们在点咖啡的时候通常会有这样的情况:
点了不同的咖啡会有不同的价格,此时我们需要一个咖啡的基类,不同的咖啡重写基类的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
我们在点咖啡的时候
相关文章推荐
- 学习PB webservice(杂记)
- 【SPOJ-HIGH】Highways【高斯消元】【Matrix Tree定理】【行列式】
- 门面模式
- ios NSFileManager 用法详解
- iOS截屏功能
- 进制转换
- 62. Unique Paths
- linux设置固定ip
- 机房重构--透过查询余额看视图的应用
- MYSQL INDEX CONDITION PUSHDOWN
- iOS学习笔记57-正则表达式在iOS中的运用
- 好用的基于jQuery的提示框插件--webui-popover
- 编程技巧笔记
- Infinispan 8 中新的 Redis 缓存存储实现
- C++ 设计模式之——简单工厂模式(SimpleFactoryPattern)
- 正则表达式基本语法
- java jvm GC 各个区内存参数设置
- 四项技术 助你提高SQL Server的性能
- iOS开发之Objective-C与JavaScript的交互
- 用设计模式来代替臃肿的ifelse层层判断