当前位置: 移动技术网 > IT编程>软件设计>设计模式 > 设计模式之装饰者模式(二)

设计模式之装饰者模式(二)

2019年04月09日  | 移动技术网IT编程  | 我要评论
欢迎大家的不嫌弃,继续和我一起学习设计模式。上一篇已经把装饰者模式的类图有了一个整体的出来,末尾说的去想想实现的代码,你实践了吗?是什么原因让你实践了呢?又是什么原因让你没有动手呢?没动手,可能是思路还不够明确是吗? 接下来,我们继续学习。通过代码实现的方式,来搞定装饰者模式。 写下代码 动手的时候 ...

欢迎大家的不嫌弃,继续和我一起学习设计模式。上一篇已经把装饰者模式的类图有了一个整体的出来,末尾说的去想想实现的代码,你实践了吗?是什么原因让你实践了呢?又是什么原因让你没有动手呢?没动手,可能是思路还不够明确是吗?

接下来,我们继续学习。通过代码实现的方式,来搞定装饰者模式。

写下代码

动手的时候来啦,我们先从beverage类下手。这不需要修改原有的设计,如下所示:

/**
 * 
 * @description: beverage是一个抽象类,有两个方法:getdescription()以及cost()
 * @author:xuyue
 */
public abstract class beverage {
    string description = "unknown beverage";
    
    // getdescription()已经在此实现了,但是cost()必须在子类中实现
    public string getdescription() {
        return description;
    }
    
    public abstract double cost();
}

然后我们继续实现condiment(调料)抽象类,也就是装饰者类:

/**
 * 
 * @description: 必须让condimentdecorator能够取代beverage,所以将condimentdecorator扩展自beverage类
 */
public abstract class condimentdecorator extends beverage {
    // 所有的调料装饰者都必须重新实现getdescription()方法,稍后说明原因
    public abstract string getdescription();
}

写饮料的代码

有了上面的基础,即已经有了基类,那我们就可以愉快的把饮料类实现了。先从浓缩咖啡(espresso)开始吧。在这,我们需要实现cost()方法以及将描述设置清楚。其他类,在代码里表现,就不在文中体现啦。

/**
 * 
 * @description:首先,让espresso扩展自beverage类,因为espresso是一种饮料
 * @author:xuyue
 */
public class espresso extends beverage {

    public espresso() {
        // 为了要设置饮料的描述,我们写了一个构造器,description继承自beverage
        description = "espresso";
    }
    
    // 需要计算espresso的价钱
    @override
    public double cost() {
        return 1.99;
    }

}

写调料代码

还记得上篇中的类图吗,根据类图我们已经完成了抽象组件(beverage),有了具体组件(houstblend),也有了抽象装饰者(condimentdecorator)。那么,就差实现具体的装饰者了,也就是我们的调料。这里是列举mocha,其他的自行实现哦。小编提供的代码里已经实现啦, 感兴趣的小伙伴,可以写完和小编的pk下。

/**
 * 
 * @description:
 * 摩卡是一个装饰者,所以让它扩展自condimentdecorator
 * condimentdecorator扩展自beverage
 * @author:xuyue
 */
public class mocha extends condimentdecorator {

    beverage beverage;
    
    public mocha(beverage beverage) {
        this.beverage = beverage;
    }
    
    @override
    public string getdescription() {
        return beverage.getdescription() + " , mocha";
    }

    @override
    public double cost() {
        return 0.20 + beverage.cost();
    }

}

供应咖啡

恭喜你,经历过之前的准备,是时候坐下来休息休息,点一杯咖啡享受下人生啦。来看看你的装饰者模式设计出来的系统吧。

写之前,我们先看看双倍摩卡咖啡的是怎么装饰的吧。其实就是上一篇中的单倍摩卡,再加一层摩卡的装饰类即可,是不是很神奇呢。

public class starbuzzcoffee {

    public static void main(string[] args) {
        // 订一杯espresso,不需要调料
        beverage beverage = new espresso();
        system.out.println(beverage.getdescription() + " $" + beverage.cost());
        
        // 订一杯双倍mocha加whip的darkroast()咖啡
        beverage beverage2 = new darkroast();
        // 用mocha装饰它
        beverage2 = new mocha(beverage2);
        // 用第二个mocha装饰它
        beverage2 = new mocha(beverage2);
        // 用whip装饰它
        beverage2 = new whip(beverage2);
        system.out.println(beverage2.getdescription() + " $" + beverage2.cost());
        
        // 订一杯调料为soy、mocha、whip的houseblend咖啡
        beverage beverage3 = new houseblend();
        beverage3 = new soy(beverage3);
        beverage3 = new mocha(beverage3);
        beverage3 = new whip(beverage3);
        system.out.println(beverage3.getdescription() + " $" + beverage3.cost());
        
    }
}

// 输出结果
espresso $1.99
dark roast coffee , mocha , mocha , whip $1.49
house blend coffee , soy , mocha , whip $1.34

目前为止,我们已经把上篇遗留下来的类图转换成了代码实现出来。当我们在后面介绍到工厂和生成器模式的时候,将会有更好的方式建立被装饰者对象。所以,尽管现在的装饰者模式存在部分缺陷,但不妨碍我们对这个模式的学习,后续的增加,只是对模式有更加深刻的认知。

所以,这次的内容就先到这里。下一篇,我们针对性的对现有jdk中的装饰者模式举个例子,并对装饰者模式做出总结。

留个小习题,在这次讲的过程中我们是加了调料, 那咖啡厅里现在都会有杯子的大小,小杯、中杯、大杯,并收取相应的价钱,该如何编写呢?先抛个砖,我们在beverage类中加上getsize()和setsize()。下次小编会给出答案噢。

ps:代码已经上传,需要查看的朋友点击此处headfirstdesign

推荐阅读

爱生活,爱学习,爱感悟,爱挨踢

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网