深入显出设计模式三——Beverage实现(装饰者模式)

深入浅出设计模式三——Beverage实现(装饰者模式)

深入显出设计模式三——Beverage实现(装饰者模式)

 

上图的实现代码见:

http://quicker.iteye.com/blog/554032

定义:
装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供比继承更有弹性的替代方案。

设计原则五:代码应该对扩展开放,对修改关闭。

Beverage系统是一个销售咖啡的订单系统,主要销售咖啡,咖啡有多种,另外有多个种类的调料。

那么如果将Beverage设为超类,其它的咖啡调料等都从这个类继承,并且每个类都有一个cost的计费方法。

类图如下:

深入显出设计模式三——Beverage实现(装饰者模式)

上面的类看起来要爆炸了。。。

我们看看使用装饰模式后的类图。

深入显出设计模式三——Beverage实现(装饰者模式)

 

http://quicker.iteye.com/blog/554032

 文中讲过一点:

 在装饰者类中使用了继承,又把父类的引用作为它的属性。

 这是因为继承能使类型保持一致,而我们要灵活的使用类的行为则需要使用组合。

继承:装饰者要与被装饰者保持一样的类型,因为装饰者必须能取代被装饰者。

组合:当我们将装饰者与组件组合时,就是加入新的行为。所得到的新的行为,不是继承自超类,而是由组合对象得来的。

所以在上图中继承Beverage抽象类,是为了有正确的类型,而不是继承它的行为。行为来自装饰者和基础组件,或与其他装饰者之间的组合关系。

在上例中正是因为使用对象组合,我们才可以把所有饮料和调料更有弹性地加以混和与匹配,比如客户同时点了多种咖啡和调料的时候。

代码如下:

package com.lwf.disign.learn.decorator;

public abstract class Beverage {

	String description = "Unknown Beverage";
	public String getDescription(){
		return description;
	}
	public abstract double cost();
}

 

 

package com.lwf.disign.learn.decorator;

public class Espresso extends Beverage {

	public Espresso(){
		description = "Espresso";
	}
	public double cost() {
		return 1.99;
	}

}

 

 

package com.lwf.disign.learn.decorator;

public abstract class CondimentDecorator extends Beverage {

	public abstract String getDescription();

}

 

 

package com.lwf.disign.learn.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 0.200 + beverage.cost();
	}

}

 

package com.lwf.disign.learn.decorator;

public class Whip extends CondimentDecorator {

	Beverage beverage;
	public Whip(Beverage beverage) {
		this.beverage = beverage;
	}
	public String getDescription() {
		return beverage.getDescription() + " Mocha";
	}

	public double cost() {
		return 0.400 + beverage.cost();
	}

}

 

测试类:

package com.lwf.disign.learn.decorator;

public class BeverageTest {

	public static void main(String[] args) {
		Beverage b = new Espresso();
		System.out.println(b.getDescription() + " $ " + b.cost());
		
		b = new Mocha(b);
		System.out.println(b.getDescription() + " $ " + b.cost());

		b = new Mocha(b);
		System.out.println(b.getDescription() + " $ " + b.cost());
		
		b = new Whip(b);
		System.out.println(b.getDescription() + " $ " + b.cost());
	}

}

 

输出结果为:

Espresso $ 1.99
Espresso Mocha $ 2.19
Espresso Mocha Mocha $ 2.39
Espresso Mocha Mocha Mocha $ 2.79

 

 

上例最后输出的就是客户点了Espresso咖啡,和两份Mocha调料和一份Whip的总消费额。