陕西小吃美食价格交流群

设计模式之装饰者模式

2022-01-16 21:28:53

如果你没了解过装饰者模式,那么请继续往下看,如果你是老司机,那么,你可以快速往下看。

开始装个13,再进入正文。

一如既往,你能从本文了解到如下信息:1. 一个简单的装饰者demo? 2. 什么是装饰者模式? 3. 总结。

来讲个需求

假如现在你有这么个需求,需要给咖啡馆编写一套收费系统。咖啡馆有卡布奇洛,拿铁,美式咖啡,浓缩咖啡……二十几种,配料包括:糖,奶油,牛奶,摩卡,奶泡……十几种,包装有外卖盒,精美咖啡杯,商务咖啡杯……七八种。需要帮忙设计一套收费系统。

第一种思路: 最死板的方法,每个咖啡种类,每种配料,每种包装都生成一个类,然后选择何种类就添加何种类的金额。

我点一杯加糖拿铁用漂亮杯子装计算价格及编写描述的代码就这么写:

  1. mResult.setText("您点了:" + new BeautifulCup().description() + new Soul().description() + new Latte().description() +  + "\n一共消费了:" + new BeautifulCup().cost() + new Soul().cost() + new Latte().cost());

第二种思路: 我们在第一种思路上进行扩展, 我们建立一个基础类Matrial,所有的咖啡类,配料类,装饰类继承这个基类。再进一步,我们想办法让用户每添加一个配料都直接计算出结果,不要等最后一次性计算。

基于上面 的思路,我需要定一杯加糖拿铁的代码如下:

  1. mResult.setText("您点了:" + new Soul(new Latte()).description() + "\n一共消费了:" + mCoffee.cost());

  1. public class Soul extends Material {

  2.    private Material mMaterial;

  3.    public Soul(Material material) {

  4.        mMaterial = material;//将选择好的类传进来

  5.    }

  6.    @Override

  7.    public int cost() {

  8.        return 2 + mMaterial.cost();//之前所有东西的价格再添加当前配料的价格

  9.    }

  10.    @Override

  11.    public String description() {

  12.        return "加糖的" + mMaterial.description();

  13.    }

  14. }

第三种思路:第二种思路的实现类还是比较多的,有多少配料,有多少咖啡就得生成多少个具体实现类,我们可以再将实现类总分成三个实现类,一个Coffee类,一个Dosing类,一个Cup类。通过枚举的方式进行分类,这样就能大大减少类的数量。这里简单列举一个Coffee类,其他依葫芦画瓢就行了。

代码如下:

  1. public class Coffee extends Material{

  2.    private final static int CAPPUCCIO = 0;

  3.    private final static int LATTE = 1;

  4.    private final static int DARK = 2;

  5.    private final static int HOUSE = 3;

  6.    private Material mMaterial;

  7.    private int type = 0 ;

  8.    public Coffee(Material material, int type) {

  9.        mMaterial = material;

  10.        this.type = type;

  11.    }

  12.    @Override

  13.    public int cost() {

  14.        int cuurCost = 0;

  15.        switch (type){

  16.            case CAPPUCCIO:

  17.                cuurCost = 22;

  18.                break;

  19.            case LATTE:

  20.                cuurCost = 25;

  21.                break;

  22.            case DARK:

  23.                cuurCost = 30;

  24.                break;

  25.            case HOUSE:

  26.                cuurCost = 35;

  27.                break;

  28.        }

  29.        if (mMaterial != null) {

  30.            return mMaterial.cost() + cuurCost;

  31.        }else{

  32.            return cuurCost;

  33.        }

  34.    }

  35.    @Override

  36.    public String description() {

  37.        String  cuurDescription = "";

  38.        switch (type){

  39.            case CAPPUCCIO:

  40.                cuurDescription = "卡布奇洛";

  41.                break;

  42.            case LATTE:

  43.                cuurDescription = "拿铁";

  44.                break;

  45.            case DARK:

  46.                cuurDescription = "烘焙";

  47.                break;

  48.            case HOUSE:

  49.                cuurDescription = "House";

  50.                break;

  51.        }

  52.        if (mMaterial != null) {

  53.            return  mMaterial.description() + cuurDescription ;

  54.        }else{

  55.            return cuurDescription;

  56.        }

  57.    }

  58. }

看完例子,下面我们来说说什么是装饰者模式?

什么是装饰者模式?

官方一点的说法可以说:动态地给对象附加职责。字面意思理解:就是给对象进行一层包装。(就好像你给咖啡添加糖,糖就可以充当装饰者的角色)。上面的例子其实就是一个典型的装饰者模式。可以根据下面的图来进行上面案例的分析:A是用户最先的咖啡,B是配料,C是杯子。当用户在调用B的method()时,B的method方法中包含了A的method的结果。同理,C的method方法包含了B的method方法的结果。


总结

啥嘛,还要总结,好吧,说下吧,这几天词比较穷呀!通过上面文章我们可以知道,装饰者模式主要用于需要给一个类动态扩展或者撤销附加职责,并且能在不修改任何底层源码的情况下进行。

最后,如果您觉得本文写的不错,就给个赞吧!如果读了本文还有疑惑或者发现可以改进的地方,请给我留言


友情链接

Copyright © 2023 All Rights Reserved 版权所有 陕西小吃美食价格交流群