zoukankan      html  css  js  c++  java
  • 设计模式——装饰者模式

    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());
        }
    }

    结果

    Suancai Noodle + Egg + SkinOfTofu
    13.0
    -----
    Beef Noodle + Egg
    14.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可以提供比继承更多的灵活性
    • 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合
    缺点:
    • 比继承更加灵活也同时意味着更加多的复杂性
    • 导致设计中出现许多小类,如果过度使用,会使程序变得很复杂
  • 相关阅读:
    datasnap 2010 为DataSnap系统服务程序添加描述
    uLanguage.pas
    cxgrid上如何取FOOTER上合计的值
    cxgrid经典用法
    datasnap 2010 DataSnap服务端和客户端发布分发方法
    php_network_getaddresses: getaddrinfo failed 原因
    查看crontab运行状态
    laravel 开启定时任务需要操作
    解决cron不执行的问题
    UPdate语句
  • 原文地址:https://www.cnblogs.com/kaituorensheng/p/9900519.html
Copyright © 2011-2022 走看看