设计模式:装饰者模式

  装饰者模式:动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。

   现在,我们有一个场景,咖啡店出售各种不同的咖啡,而不同的咖啡中可以加入各种不同的调料,根据咖啡种类和加入的调料来计算价格。下面我们就用代码来简单实现下这个场景,也就是装饰者模式,其中咖啡为主体,调料是用来装饰咖啡的,比如想要一杯摩卡和奶泡的深焙咖啡,那么要做的是:

  1:拿一个深焙咖啡DarkRoast对象

  2:以摩卡Mocha对象来进行装饰

  3:以奶泡Whip对象进行装饰

  4:调用cost方法,并依赖委托将调料价格加上去。

  好了,直接上代码理解装饰者模式吧。

  第一步:先创建一个基类,所有咖啡和调料都是扩展自这个类的。这就说明装饰者和被装饰者对象都有相同的超类型。

//基类
public abstract class Coffer {
    String descirption = "Unknown Coffer";
    
    public String getDescription(){
        return descirption;
    }
    
    //所有子类必须实现这个方法来计算价格
    public abstract double cost();
}

  第二步:创建一个调料的抽象类,也就是装饰者类,具体的装饰者类实现此类。

//抽象的装饰者,调料类,扩展自Coffer
public abstract class Condiment extends Coffer{
    public abstract String getDescription();
}

  第三步:创建具体的咖啡类。

//具体的咖啡种类——浓缩咖啡类
public class Espresso extends Coffer{
    
    public Espresso(){
        descirption = "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}
//具体的咖啡种类——深焙咖啡类
public class DarkRoast extends Coffer{
        
    public DarkRoast(){
        descirption = "DarkRoast";
    }

    @Override
    public double cost() {
        return 0.88;
    }
}

  第四步:创建具体的调料类

//具体的装饰者,摩卡调料
public class Mocha extends Condiment {
    //用于记录被装饰者,这里是在构造方法中将参数记录到咖啡的实例变量中,你也可以使用get/set方法
    Coffer coffer;
    
    public Mocha(Coffer coffer){
        this.coffer = coffer;
    }
    
    @Override
    public String getDescription() {
        return coffer.getDescription() + ", Mocha";
    }

    @Override
    public double cost() {
        return 0.2 + coffer.cost();
    }
}
//具体的装饰者,奶泡调料
public class Whip  extends Condiment{
    Coffer coffer;
    
    public Whip(Coffer coffer){
        this.coffer = coffer;
    }
    
    @Override
    public String getDescription() {
        return coffer.getDescription() + ", Whip";
    }

    @Override
    public double cost() {
        return 0.15 + coffer.cost();
    }
}

  第五步:测试

public class Test {
    public static void main(String[] args) {
        //来一杯Espresso咖啡
        Coffer coffer = new Espresso();
        System.out.println(coffer.getDescription() + ",价格:" + coffer.cost());
        
        //来一杯深焙咖啡,加入2分摩卡和1分奶泡
        Coffer coffer2 = new DarkRoast();
        coffer2 = new Mocha(coffer2);
        coffer2 = new Mocha(coffer2);
        coffer2 = new Whip(coffer2);
        System.out.println(coffer2.getDescription() + ",价格:" + coffer2.cost());
    }
}

  运行结果:

  

  好了,这就是一个简单的装饰者模式了。在Java的API中,你可以发现,有关IO类就是采用装饰者模式的,如:

      LineNumberInputStream inputStream = new LineNumberInputStream(new BufferedInputStream(new FileInputStream(fileName)));

  顶层类都是InputStream,具体这里不讲解了。

 

  下一节:工厂模式

posted @ 2017-03-04 15:17  哀&RT  阅读(142)  评论(0编辑  收藏  举报