因为近期研究了一下java的设计模式在网上看到一些很好的例子,特借鉴下来,以作日后查看,想看具体,请查看
原文:http://blog.csdn.net/zhshulin/article/details/38665187#reply
1、概念
装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
但是纯粹的装饰模式很难找到,大多数的装饰模式的实现都是“半透明”的,而不是完全透明的。换言之,允许装饰模式改变接口,增加新的方法。半透明的装饰模式是介于装饰模式和适配器模式之间的。适配器模式的用意是改变所考虑的类的接口,也可以通过改写一个或几个方法,或增加新的方法来增强或改变所考虑的类的功能。
大多数的装饰模式实际上是半透明的装饰模式,这样的装饰模式也称做半装饰、半适配器模式
2、针对的问题
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。不改变接口的前提下,增强所考虑的类的性能。
何时使用:
1)需要扩展一个类的功能,或给一个类增加附加责任。
2)需要动态的给一个对象增加功能,这些功能可以再动态地撤销。
3)需要增加一些基本功能的排列组合而产生的非常大量的功能,从而使继承变得 不现实。
3、角色组成
l 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
l 具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类
l 装饰角色(Decorator):持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口
l 具体装饰角色(ConcreteDecorator):负责给构件对象“贴上”附加的责任
4、举例说明
咖啡是一种饮料,咖啡的本质是咖啡豆+水磨出来的。咖啡店现在要卖各种口味的咖啡,如果不使用装饰模式,那么在销售系统中,各种不一样的咖啡都要产生一个类,如果有4中咖啡豆,5种口味,那么将要产生至少20个类(不包括混合口味),非常麻烦。使用了装饰模式,只需要11个类即可生产任意口味咖啡(包括混合口味)。
4.1、类图
4.2、源码
Beverage饮料接口
**
* 饮料接口
* @author Administrator
*
*/
public interface Beverage {
//返回商品描述
public String getDescription();
//返回价格
public double getPrice();
}
CoffeeBean1——具体被装饰的对象类1
public class CoffeeBean1 implements Beverage {
private String description = "选了第一种咖啡豆";
@Override
public String getDescription() {
return description;
}
@Override
public double getPrice() {
return 50;
}
}
CoffeeBean2——具体被装饰的对象类2
public class CoffeeBean2 implements Beverage {
private String description = "第二种咖啡豆!";
@Override
public String getDescription() {
return description;
}
@Override
public double getPrice() {
return 100;
}
}
Decorator——装饰类
public class Decorator implements Beverage {
private String description = "我只是装饰器,不知道具体的描述";
@Override
public String getDescription() {
return description;
}
@Override
public double getPrice() {
return 0; //价格由子类来决定
}
}
Milk——具体装饰类,给咖啡加入牛奶
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; //20表示牛奶的价格
}
}
Mocha——给咖啡加入摩卡
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; //30表示摩卡的价格
}
}
Soy——给咖啡加入豆浆
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; //30表示豆浆的价格
}
}
测试类:
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());
}
}
测试结果: