您的位置:首页 > 其它

装饰者模式(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  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: