标签:
某一个商店卖咖啡,咖啡有很多种,不管以后它变成什么,刚开始它都来自于一杯普通的咖啡,我们把这个Coffee设置成一个接口,它有两种方法:说明它是什么咖啡,以及它卖多少钱。
public interface Coffee {
public void getDescription();
public void cost();
}
现在我们开始设计其他咖啡,如加了牛奶的咖啡,加了巧克力的咖啡等等。
咖啡可以有各种各样的调料,根据调料的不同,最后咖啡的种类就不同,能卖多少钱也就不同。
假设有三种调料,他们可以随意搭配,那么可以产生7种咖啡。
这时候可以把每一种都单独设置成一个类。
那么假如有4种调料
会有16种。。。
诸如此类,如果把每一种咖啡都设计成一个类,会出现类"类爆炸"。
这时候,可以使用装饰器模式完成这些需求。
装饰器模式分为以下几个角色:
抽象产品角色
具体产品类角色
抽象装饰器角色
具体装饰器角色
直接上代码:
抽象产品类,它是其他三种角色的爸爸,咖啡,牛奶,糖水等都需要继承它。
public abstract class Beverage {
public void cost() {
}
}
抽象装饰类,它的子类是具体的装饰类,如添加牛奶,添加糖水之类的。
public abstract class CondimentDecorator extends Beverage {
}
具体产品类
public class PureCoffee extends Beverage {
public void cost() {
System.out.println("Buy coffee!");
System.out.println("6-RMB!");
}
}
这个具体产品可以加糖水,也可以加牛奶,在这种场景下,先添加糖水还是牛奶是没有区别的。
具体装饰类(糖水和牛奶)
牛奶装饰器
public class Milk extends CondimentDecorator {
Beverage beverage;
public Milk(Beverage beverage) {
this.beverage = beverage;
}
public void cost() {
beverage.cost();
System.out.println("Add new condiment:milk");
System.out.println("9-RMB");
}
}
糖水装饰器
public class Sugar extends CondimentDecorator {
Beverage beverage;
public Sugar(Beverage beverage) {
this.beverage = beverage;
}
public void cost() {
System.out.println("Add new condiment:sugar");
System.out.println("5-RMB!");
}
}
测试
public class BeverageTest {
@Test
public void test(){
PureCoffee pureCoffee = new PureCoffee();
Beverage beverage = new Milk(pureCoffee);//添加牛奶
beverage.cost();
beverage = new Sugar(beverage);//添加糖水
beverage.cost();
}
}
//Buy coffee!
//6-RMB!
//Add new condiment:milk
//9-RMB
//Add new condiment:sugar
//5-RMB!
在Java IO中使用的就是这种设计模式
可以通过继承FilterInputStream这个抽象装饰角色,实现一个具体的装饰角色Lower,用来装饰FileInputStream这个具体产品,他们的爸爸都是InputStream(抽象产品)。
public class Lower extends FilterInputStream {//具体装饰角色
public Lower(InputStream in) {
super(in);
}
public int read() throws IOException {
int x = super.read();
return (x == -1 ? x : Character.toLowerCase((char) x));
}
}
测试:
@Test
public void test1() throws IOException {
int c;
InputStream in = new Lower(new BufferedInputStream(new FileInputStream("/Users/roomy/Desktop/1.txt")));
while ((c = in.read()) >= 0) {
System.out.print((char)c);
}
in.close();
}
//YDSOFJFsfsafa
//ydsofjfsfsafa
以上:)
参考资料:
Head First 设计模式
标签:
原文地址:http://www.cnblogs.com/zhangxd-stn/p/dp1.html