装饰者模式(Decorator Pattern)

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  








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值