标签:
某一个商店卖咖啡,咖啡有很多种,不管以后它变成什么,刚开始它都来自于一杯普通的咖啡,我们把这个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