• 设计模式——装饰者模式


    装饰者模式

    1. 定义

    装饰者模式动态的将责任附加到对象上。如要扩展功能,装饰者提供了比继承更有弹性的替代方案。

    2. 类图

    3. Example

    假如有这样一个需求:有一天,奶茶店的老板喊你给他们做一个简单版的计算价格程序。新店开张,供应的饮料有奶茶(8元)、红茶(7元)、绿茶(5元)三种,提供的配料有波霸1元,布丁5元,红豆3元。

    则可如下设计:

    Component及其实现如下:

    package com.gitlearning.hanldegit.patterns.decorator;
    
    /**
     * 相当于Component
     */
    public abstract class Beverage {
        String description = "Unkown beverage";
    
        public String getDescription() {
            return description;
        }
    
        public abstract double cost();
    
    }
    
    class MilkTea extends Beverage {
        @Override
        public String getDescription() {
            return "奶茶";
        }
    
        @Override
        public double cost() {
            return 8.00;
        }
    }
    
    class RedTea extends Beverage {
        @Override
        public String getDescription() {
            return "红茶";
        }
    
        @Override
        public double cost() {
            return 7.00;
        }
    }
    
    class GreenTea extends Beverage {
        @Override
        public String getDescription() {
            return "绿茶";
        }
    
        @Override
        public double cost() {
            return 5.00;
        }
    }
    
    

    Decorator及其实现如下:

    package com.gitlearning.hanldegit.patterns.decorator;
    
    public abstract class CondimentDecorator extends Beverage {
        @Override
        public abstract String getDescription();
    
    
    }
    
    class RedBean extends CondimentDecorator {
    
        Beverage beverage;
    
        public RedBean(Beverage beverage) {
            this.beverage = beverage;
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription() + "添加红豆";
        }
    
        @Override
        public double cost() {
            return beverage.cost() + 3.00;
        }
    }
    
    class Pudding extends CondimentDecorator {
        Beverage beverage;
    
        public Pudding(Beverage beverage) {
            this.beverage = beverage;
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription() + "添加布丁";
        }
    
        @Override
        public double cost() {
            return beverage.cost() + 5.00;
        }
    }
    
    class Boba extends CondimentDecorator {
        Beverage beverage;
    
        public Boba(Beverage beverage) {
            this.beverage = beverage;
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription() + "添加波霸";
        }
    
        @Override
        public double cost() {
            return beverage.cost() + 1.00;
        }
    }
    

    测试代码如下:

    package com.gitlearning.hanldegit.patterns.decorator;
    
    import org.junit.jupiter.api.Test;
    
    public class DecoratorTest {
        @Test
        void test() {
            // 来一杯加波霸和布丁的奶茶
            Beverage milkTea = new MilkTea();
            milkTea = new Pudding(milkTea);
            milkTea = new Boba(milkTea);
            System.err.println(milkTea.getDescription() + "¥"+ milkTea.cost());
    
            // 来一杯加红豆的绿茶
            Beverage greenTea = new GreenTea();
            greenTea = new RedBean(greenTea);
            System.err.println(greenTea.getDescription() + "¥"+ greenTea.cost());
    
            // 来一杯加红豆、布丁、波霸的红茶
            Beverage redTea = new RedTea();
            redTea = new Pudding(redTea);
            redTea = new Boba(redTea);
            redTea = new RedBean(redTea);
            System.err.println(redTea.getDescription() + "¥"+ redTea.cost());
        }
    }
    
    

    发现输出为:

    奶茶添加布丁添加波霸¥14.0
    绿茶添加红豆¥8.0
    红茶添加布丁添加波霸添加红豆¥16.0
    

    4. 使用

    1. Java I/O

    InputStream作为抽象Component,

    Component,像BufferedInputStream装饰了FileInputStream,增加了readLine()和缓冲输入,LineNumberInputStream()则增加了计算行数的能力。

    2. Mybatis

    5.其他

    1. 装饰者会导致类中出现许多的小对象,如果过度使用,会让程序变得复杂。
    2. 装饰者可以在被装饰者的行为前面或者后面加上自己的行为。
    3. 可以用无数个装饰者包装一个组件。
    当你准备好了,机会来临的时候,你才能抓住
  • 相关阅读:
    dojo自定义Widget
    奇怪的JS
    Dojo Widget系统(转)
    JS 中Promise 模式
    Structs 原理图
    ArcGIS Engine Style文件操作
    dojo.hitch 原理
    Android:解决cannot find zipalign的问题
    Bootstrap:解决Bootstrap下拉框需要双击才能打开的问题
    Clojure:添加gzip功能
  • 原文地址:https://www.cnblogs.com/studentytj/p/11324687.html
Copyright © 2020-2023  润新知