[java]代码库
使用装饰者模式可以很好的解决上面的两个问题、这里不再绕弯子、直接实现。具体的思想内涵可以自己慢慢揣摩。有时间补上类结构图(也可以看Head First Design Pattern这本书的Decorating Object这一章)。
1、装饰者模式要求装饰器和组件是同一类型、那么我们先给所有咖啡一个抽象类——Beverage(当然也可以使用接口、原则就是尽量减少对源代码的改动、如果源代码是抽象类并且没有什么问题、何必还要fix它呢)——Beverage代码:
[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
package com.chy.dp.decorator;
public abstract class Beverage {
String description = "no description";
public String getDescription (){
return description;
}
public abstract double cost();
}
2、创建四种咖啡模型、也就是组件、并实现Beverage抽象类、这里列举一个——HouseHand代码:
[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
package com.chy.dp.decorator;
public class HouseHand extends Beverage {
public HouseHand() {
super();
description = "HouseHand";
}
/**
* the price of HouseHand is 8.9$ .
*/
@Override
public double cost() {
return 8.9;
}
}
3、定义一个所有装饰器的抽象类、继承与Beverage、这样以后如果有新添加的调料我们就可以扩展一个调料装饰器来与当前的几种咖啡组合、而不用动原来的任何代码!open for extension, but closed for modification!——CondimentDecorator代码:
[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
package com.chy.dp.decorator;
public abstract class CondimentDecorator extends Beverage {
/**
* 提供一个必须要实现的获取当前组合的描述信息的方法。
* 方便观察结果。
*/
public abstract String getDescription();
}
4、定义具体的装饰类:MochaDecorator、MilkDecorator、WhipDecorator、SoyDecorator、以MochaDecorator为例——MochaDecorator代码:
[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
package com.chy.dp.decorator;
public class MochaDecorator extends CondimentDecorator {
Beverage beverage;
public MochaDecorator(Beverage beverage) {
super();
this.beverage = beverage;
}
/**
* 返回被包装的组合或者组件的描述加上当前包装信息。
*/
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
@Override
public double cost() {
return beverage.cost() + 10.3;
}
}
5、在Client端我们就可以任意的指定组合了——Client代码:
[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
package com.chy.dp.decorator;
@SuppressWarnings("unused")
public class Client {
public static void main(String[] args) {
Beverage darkRoast = new DarkRoast();
Beverage espresso = new Espresso();
Beverage decaf = new Decaf();
Beverage houseHand = new HouseHand();
// Dark Roast with double Mocha
Beverage decoratorMocha = new MochaDecorator(darkRoast);
Beverage decoratorMocha2 = new MochaDecorator(decoratorMocha);
// Espresso + Soy
Beverage espresso_Soy = new SoyDecorator(espresso);
System.out.println("discription : " + espresso_Soy.getDescription()
+ "===price : " + espresso_Soy.cost() + "$");
System.out.println("description : " + decoratorMocha2.getDescription()
+ "===price : " + decoratorMocha2.cost() + "$");
}
}