设计模式——装饰模式(Decorator)
概念
装饰模式又名包装(Wrapper)模式。装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
针对的问题
动态的给一个对象添加一些额外的职责,就增加功能来说,Decorator模式相比生成子类更为灵活。不改变接口的前提下,增强所考虑的类的性能。
何时使用:
- 需要扩展一个类的功能,或给一个类增加附加责任。
- 需要动态的给一个对象增加功能,这些功能可以再动态地撤销。
- 需要增加一些基本功能的排列组合而产生的非常大量的功能,从而使继承变得不现实。
总的来说,就是给原有的类增加新的功能,假如有5种咖啡,4种配料(糖和牛奶,蜂蜜,巧克力),如果要生成子类的话就会有5×4=20个子类,这样就太多了,通过装饰器模式就只用写5+4+装饰器类这么多就好,装饰器的意思就是给原来的咖啡加入装饰(这里的装饰指的就是配料)。
角色构成
抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
装饰角色(Decorator):持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口,也就是要有原来抽象构件中的全部方法。
具体装饰角色(ConcreteDecorator):负责给构件对象“贴上”附加的责任。

举例
还是刚才的咖啡的例子,

这里的抽象构件(Component)角色就是饮料,饮料接口对各种咖啡进行限制。
具体构件(ConcreteComponent)角色 就是各种咖啡。
现在要往咖啡中加入配料了
装饰器(Decorator) 加了一种配料的咖啡,但是具体加了什么配料不知道,由具体的子类决定。
具体装饰角色 就是各种咖啡以及加了配料的类,
1 2 3 4 5 6 7 8 9
|
public interface Beverage { public String getDescription(); public double getPrice(); }
|
1 2 3 4 5 6 7 8 9 10 11
| public class CoffeeBean1 implements Beverage { private String description = "选了第一种咖啡豆"; @Override public String getDescription() { return description; } @Override public double getPrice() { return 50; } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class CoffeeBean2 implements Beverage { private String description = "第二种咖啡豆!"; @Override public String getDescription() { return description; } @Override public double getPrice() { return 100; } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class Decorator implements Beverage { private String description = "我只是装饰器,不知道具体的描述"; @Override public String getDescription() { return description; } @Override public double getPrice() { return 0; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Milk extends Decorator{ private String description = "加了牛奶!"; private Beverage beverage = null; public Milk(Beverage beverage){ this.beverage = beverage; } public String getDescription(){ return beverage.getDescription()+"\n"+description; } public double getPrice(){ return beverage.getPrice()+20; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Mocha extends Decorator { private String description = "加了摩卡!"; private Beverage beverage = null; public Mocha(Beverage beverage){ this.beverage = beverage; } public String getDescription(){ return beverage.getDescription()+"\n"+description; } public double getPrice(){ return beverage.getPrice()+49; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Soy extends Decorator { private String description = "加了豆浆!"; private Beverage beverage = null; public Soy(Beverage beverage){ this.beverage = beverage; } public String getDescription(){ return beverage.getDescription()+"\n"+description; } public double getPrice(){ return beverage.getPrice()+30; } }
|
1 2 3 4 5 6 7 8 9 10
| public class Test { public static void main(String[] args) { Beverage beverage = new CoffeeBean1(); beverage = new Mocha(beverage); beverage = new Milk(beverage); System.out.println(beverage.getDescription()+"\n加了摩卡和牛奶的咖啡价格:"+beverage.getPrice()); } }
|