标签:对象 main class 咖啡 ebean 扩展 责任 color 方式
转载请注明出处!!。http://blog.csdn.net/zhonghuan1992
全部配套代码均在github上:https://github.com/ZHONGHuanGit/DesignPattern
装饰者(Decorator)模式又叫包装模式。用组合的方式来拓展对象的功能,是继承关系的一个替代方案。
定义说明:装饰者模式动态地将责任附加到对象上,若要扩展功能,装饰着提供了比继承更富有弹性的替代方案。
从实例中体会:
实例来自 HeadFirst一书(建议读该书。样例太赞了)。是星巴克的样例。
星巴克的咖啡非常有名(穷学生,如今喝不起o(╯□╰)o)。
他们供应非常多种类的咖啡。
一開始他们的类设计是以下这种。
可是由于购买咖啡的时候,会增加更重调料,比方:蒸奶(Steamed Milk)。豆浆(Soy),摩卡(Mocha,也就是巧克力风味的),或者覆盖奶泡。星巴克会针对不同的调料收取不一样的费用。所以订单系统必须考虑这些。想想,一開始我们遇到这样的问题会怎么做,让每一个特别的咖啡豆+调料都自成一个类,似乎能够解决这个问题。可是。假设调料非常多,咖啡豆种类不少的话,总的类的数量=咖啡豆种类*调料数量。事实上挺多类的。这样是不行的。
那怎么办。在Beverage本身下手?设计成以下这种结构?
学了开闭原则(忘了能够看这里)。我们明确,这样的做法违法了开闭原则。另一点。还记得组合复用原则么?优先使用组合而不是继承。这里。应该优先考虑组合。
在这里使用装饰者模式来解决。它是这种。最先開始,我们选择咖啡豆种类。这里选择种类1
然后加入了摩卡(Mocha)调料。使用摩卡(Mocha)来装饰咖啡豆1
接着,再加点牛奶(milk),
当计算价格的时候。我们从咖啡豆開始算起到最外面,或者从最外面開始算起到最里面,都可以算出价格来。
装饰者模式类图:
从上面的类图中。有四个角色:
1 抽象构件(Component):给出一个抽象接口,以规范准备接收附加责任的对象
2 详细构件(ConcreteComponent):定义一个将要接受附加东西的类
3 装饰角色(Decorator):一般的装饰者,详细给详细构件装饰的任务延迟到详细装饰者
4 详细装饰者(ConcreteDecorator):通过持有详细构件。附加给详细构件一些方法和属性。
针对上面的样例。我们的解决方式的类图为:
解决方式的代码吐下:
interface Beverage{ String description = "unknown beverage"; public String getDescription();//返回描写叙述的 public double cost();//返回价格的 } class CoffeeBean1 implements Beverage{ String description = "选了咖啡豆1:"; public String getDescription(){ return description; } public double cost(){ return 30;//基本价格30元 } } class CoffeeBean2 implements Beverage{ String description = "选了咖啡豆2:"; public String getDescription(){ return description; } public double cost(){ return 28;//基本价格28元 } } class Decorator implements Beverage{ String description = "unknown 装饰"; Beverage beverage; public String getDescription(){ return description; } public double cost(){ return 0;//由子类来决定详细的装饰价格 } } class Milk extends Decorator{ String description = "加了牛奶"; public Milk(Beverage beverage){ this.beverage=beverage; } public String getDescription(){ return beverage.getDescription()+"\n"+description;//还有被装饰者的描写叙述 } public double cost(){ return 5+beverage.cost();//加牛奶的价格是5元,还得加上里面beverage的价格 } } class Soy extends Decorator{ String description = "加了豆浆"; public Soy(Beverage beverage){ this.beverage=beverage; } public String getDescription(){ return beverage.getDescription()+"\n"+description;//还有被装饰者的描写叙述 } public double cost(){ return 4+beverage.cost();//加豆浆的价格是4元,还得加上里面beverage的价格 } } class Mocha extends Decorator{ String description = "加了摩卡"; public Mocha(Beverage beverage){ this.beverage=beverage; } public String getDescription(){ return beverage.getDescription()+"\n"+description;//还有被装饰者的描写叙述 } public double cost(){ return 6+beverage.cost();//加摩卡的价格是6元,还得加上里面beverage的价格 } }
測试代码:
public class Main{ public static void main(String[] args){ Beverage coffee=new CoffeeBean1();//一開始选了咖啡豆1 coffee=new Mocha(coffee);//加了摩卡 coffee=new Milk(coffee);//加了牛奶 System.out.println(coffee.getDescription()); System.out.println("咖啡的价格为:"+coffee.cost()); } }
结果:
何时使用装饰者模式:
1须要扩展一个类的功能。或给一个类添加附加责任。
2须要动态的给一个对象添加功能,这些功能能够再动态地撤销。
3须要添加一些基本功能的排列组合而产生的很大量的功能,从而使继承变得不现实。
装饰者模式长处:
1装饰者模式与继承关系的目的都是要扩展对象的功能,可是装饰者模式能够提供比继承很多其它的灵活性。装饰者模式同意系统动态的决定是否须要装饰。而继承关系早系统执行前就决定了。
2通过使用不同的装饰者的排列组合,能够有非常多的组合。
缺点:装饰者模式会导致设计中出现很多小对象。假设过度使用,会让程序变的更复杂。而且很多其它的对象会是的差错变得困难,特别是这些对象看上去都非常像。
标签:对象 main class 咖啡 ebean 扩展 责任 color 方式
原文地址:http://www.cnblogs.com/gavanwanggw/p/6818718.html