装饰者模式(Decorator Pattern)
2015-10-26 23:00
459 查看
1.问题引出:
一家咖啡店,出售各种饮料咖啡。每种饮料有其自己的配料和价格(配料不同,价格不一)。有一个抽象类饮料(beverage),所有饮料都继承自这个类。有添加了不同配料的咖啡(奶milk,豆浆soy,摩卡mocha等等),这样就形成了很多种咖啡,加奶和豆浆的houseblend,加奶、豆浆和摩卡的houseblend,加奶的DarkRoast等等很多种,如果要这样的话,就会出现很多类,无法管理和重用代码。
Decorator Pattern采取的方式:以饮料为主体,然后在运行时以调料来“装饰”(decorate)饮料。
装饰者和被装饰对象有相同的超类型;
可以用一个或者多个装饰者包装一个对象;
既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以使用装饰过的对象代替它;
装饰者可以在锁委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的(例如,计算自己配料的价格,description中添加自己的描述)。
对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地来装饰对象。
2.定义装饰者模式:
1.装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。(Head First定义)在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。(百科定义)
2.设计原则:类应该对扩展开发,对修改关闭。
3.目标:允许类容易扩展,在不修改现有代码的情况下,就可搭配新的行为。
4.装饰者对象包着被装饰者对象。
3.类图设计:
4.代码实现:
Beverage基础类,所有饮料(基础类)继承该类,所有调料(牛奶、豆浆等等)装饰该类。Beverage.java
package net.pmpa.decorator; //基类可以是抽象类,也可以是接口 public abstract class Beverage { protected String description = "Unknown Beverage"; public String getDescription(){ return this.description; } //每个子类会添加一些新的内容加到这个方法 public abstract double cost(); }
饮料,基础类继承自该类。不做“装饰”,需要重写cost方法,并且通过对成员变量description赋值,来区别getDescription():
DarkRost.java
package net.pmpa.decorator;
public class DarkRost extends Beverage {
public DarkRost(){
description = "Dark Rost Coffe";
}
public double cost()
{
return .99;
}
}
Decaf.java
package net.pmpa.decorator;
public class Decaf extends Beverage {
public Decaf(){
description = "Decaf Coffe";
}
@Override
public double cost() {
return 1.05;
}
}
Espresso.java
package net.pmpa.decorator;
public class Espresso extends Beverage {
public Espresso(){
description = "Espresso Coffe";
}
public double cost()
{
return 1.99;
}
}
HouseHold.java
package net.pmpa.decorator;
public class HouseHold extends Beverage {
public HouseHold(){
description = "HouseHold Coffe";
}
public double cost()
{
return 0.89;
}
}
调料(装饰者)必须继承CondimentDecorator类,这个类只有一个abstract方法getDescription()
CondimentDecorator.java
package net.pmpa.decorator;
public abstract class CondimentDecorator extends Beverage{
//让子类必须重新实现getDescription()。
public abstract String getDescription();
}
Milk.java
package net.pmpa.decorator;
public class Milk extends CondimentDecorator{
Beverage beverage ;
public Milk(Beverage beverage)
{
this.beverage = beverage;
}
public String getDescription()
{
return beverage.getDescription()+","+"Milk";
}
//自己的价钱(0.1) + 加上被它装饰的对象的价钱(beverage.cost())
public double cost(){
return 0.1+beverage.cost();
}
}
Mocha.java
package net.pmpa.decorator;
public class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
public String getDescription()
{
return beverage.getDescription()+","+"Mocha";
}
public double cost()
{
return beverage.cost()+ 0.2;
}
}
Whip.java
package net.pmpa.decorator;
public class Whip extends Beverage {
Beverage beverage;
public Whip(Beverage beverage){
this.beverage = beverage;
}
public String getDescription()
{
return beverage.getDescription()+","+"Whip";
}
public double cost()
{
return beverage.cost()+ 0.1;
}
}
测试类,Starbucks.java
package net.pmpa.decorator;
public class Starbucks {
public static void main(String[] args) {
// TODO Auto-generated method stub
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription()+" $"+beverage.cost());
Beverage beverage2 = new DarkRost();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription()+" $"+beverage2.cost());
}
}
执行结果:
Espresso Coffe $1.99
Dark Rost Coffe,Mocha,Mocha,Whip $1.49
Dark Rost Coffe->Mocha->Mocha->Whip
0.99+0.2+0.2+0.1 = 1.49
相关文章推荐
- HDU 3172 Virtual Friends // 并查集,字典树
- OC整理
- 深入理解Java接口和抽象类
- Java开发所需架包官方下载
- 第一章 面向系统架构的系统工程
- 2015第44周一
- Apache Maven 入门篇 ( 上 )
- 第二百零七天 how can I坚持
- 痛迅企鹅修改版私密分享_版本不新但异常给力
- 23种设计模式
- HA 高可用
- 一类DP问题的分析(划分DP)
- 一致性哈希算法(consistent hashing)
- nginx+nginx-rtmp-module+ffmpeg搭建流媒体服务器
- 关于equals的一些看法
- 完成端口
- 46.Rotate List
- 题目
- [BZOJ1641][Usaco2007 Nov]Cow Hurdles 奶牛跨栏
- Scala学习笔记<基本数据结构>