java设计模式——装饰模式(Decorator)

因为近期研究了一下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());

    }
}

测试结果:
这里写图片描述

发布了19 篇原创文章 · 获赞 62 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/LSKCGH/article/details/78897444