为了账号安全,请及时绑定邮箱和手机立即绑定

设计模式——装饰者模式

标签:
设计

1. 情景

面馆开张了,主营2种面:酸菜面、牛肉面;外加2种配料:鸡蛋、豆皮

装饰者模式来设计这一订单系统:

满足要求:可以返回点的名称、计算总价格

回到顶部

2. 设计

大体思路:

这里要说的是鸡蛋、豆皮是装饰者,为了让他可以任意的加配料,返回仍是面条类。

类设计图:

回到顶部

3. 实现

面条抽象类

复制代码

public abstract class Noodle {
    String description = "Unknown Name";    public String getDescription() {        return description;
    }    public abstract double cost();
}

复制代码

装饰者抽象类

public abstract class CondimentDecorator extends Noodle {
    @Override    public abstract String getDescription();
}

面条具体类--酸菜面

复制代码

public class SuancaiNoodle extends Noodle{
    SuancaiNoodle() {
        description = "Suancai Noodle";
    }
    @Override    public double cost() {        return 10;
    }
}

复制代码

面条具体类--牛肉面

复制代码

public abstract class Noodle {
    String description = "Unknown Name";    public String getDescription() {        return description;
    }    public abstract double cost();
}

复制代码

配料具体类--鸡蛋

复制代码

public class Egg extends CondimentDecorator{    private Noodle noodle;
    Egg(Noodle noodle) {        this.noodle = noodle;
    }
    @Override    public String getDescription() {        return noodle.getDescription() + " + Egg";
    }

    @Override    public double cost() {        return noodle.cost() + 2;
    }
}

复制代码

配料具体类--豆皮

复制代码

public class SkinOfTofu extends CondimentDecorator{    private Noodle noodle;

    SkinOfTofu(Noodle noodle) {        this.noodle = noodle;
    }

    @Override    public String getDescription() {        return noodle.getDescription() + " + SkinOfTofu";
    }

    @Override    public double cost() {        return noodle.cost() + 1;
    }
}

复制代码

回到顶部

4. 测试

复制代码

public class NoodleTest {    public static void main(String[] args) {
        Noodle suancai = new SuancaiNoodle();
        Noodle addEgg = new Egg(suancai);
        Noodle addEggSkin = new SkinOfTofu(addEgg);
        System.out.println(addEggSkin.getDescription());
        System.out.println(addEggSkin.cost());

        System.out.println("-----");

        Noodle beef = new BeefNoodle();
        Noodle addEgg2 = new Egg(beef);
        System.out.println(addEgg2.getDescription());
        System.out.println(addEgg2.cost());
    }
}

复制代码

结果

?

12345Suancai Noodle + Egg + SkinOfTofu13.0-----Beef Noodle + Egg14.0

回到顶部

5.java  I/O

其中InputStream是抽象组件

其下一列如FileInputStream是抽象装饰者,BufferedInputStream是具体装饰者

用法举例

复制代码

public class ReadFileTest {    public static void main(String[] args) {        try {
            FileInputStream fis = new FileInputStream("jihite/test.json");
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedInputStream bis2 = new BufferedInputStream(bis);            byte[] b = new byte[bis2.available()];
            bis2.read(b);

            System.out.println(new String(b));
            bis2.close();
        }        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

复制代码

回到顶部

6. 归纳

定义:

在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

设计原则:

  • 多组合、少继承

  • 对扩展开放、对修改关闭

优点:

  • Decorator模式与继承关系的都是要扩展对象,但是Decorator可以提供比继承更多的灵活性

  • 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合

缺点:

  • 比继承更加灵活也同时意味着更加多的复杂性

  • 导致设计中出现许多小类,如果过度使用,会使程序变得很复杂

原文出处:https://www.cnblogs.com/kaituorensheng/p/9900519.html  

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消