zoukankan      html  css  js  c++  java
  • Java设计模式系列之装饰者模式

    装饰者模式的定义

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

    装饰者模式的UML类图

    一般来说装饰者模式有下面几个参与者:

    • Component:装饰者和被装饰者共同的父类,是一个接口或者抽象类,用来定义基本行为
    • ConcreteComponent:定义具体对象,即被装饰者
    • Decorator:抽象装饰者,继承自Component,从外类来扩展ConcreteComponent。对于ConcreteComponent来说,不需要知道Decorator的存在,Decorator是一个接口或抽象类
    • ConcreteDecorator:具体装饰者,用于扩展ConcreteComponent

    注:装饰者和被装饰者对象有相同的超类型,因为装饰者和被装饰者必须是一样的类型,这里利用继承是为了达到类型匹配,而不是利用继承获得行为

    利用继承设计子类,只能在编译时静态决定,并且所有子类都会继承相同的行为;利用组合的做法扩展对象,就可以在运行时动态的进行扩展。装饰者模式遵循开放-关闭原则:类应该对扩展开放,对修改关闭利用装饰者,我们可以实现新的装饰者增加新的行为而不用修改现有代码,而如果单纯依赖继承,每当需要新行为时,还得修改现有的代码。

    example:

    /**
     * @author yaoshw
     */
    public class TestMyIdea {
        public static void main(String[] args) {
    
            //不添加任何调料的饮料A
            Beverage beverage = new APart();
            System.out.println("Apart:" + beverage.getDescription() + "," + beverage.cost());
    
            //添加摩卡调料的饮料B
            Beverage beverage1 = new Mocha(new BPart());
            System.out.println("Bpart:" + beverage1.getDescription() + "," + beverage1.cost());
    
            //添加双份摩卡的饮料C
    
            Beverage beverage2 = new Mocha(new Mocha(new CPart()));
            System.out.println("Cpart:" + beverage2.getDescription() + "," + beverage2.cost());
    
            //添加一份摩卡、一份豆浆的饮料D
    
            Beverage beverage3 = new Soy(new Mocha(new DPart()));
            System.out.println("Dpart:" + beverage3.getDescription() + "," + beverage3.cost());
    
    
        }
    }
    
    /**
     * 抽象类,相当于Component:cost方法和getDescription方法
     */
    abstract class Beverage {
    
        String description = "UnKnownBeverage";
    
        public String getDescription() {
            return description;
        }
    
        public abstract double cost();
    }
    
    abstract class CondimentDerector extends Beverage {
        @Override
        public abstract String getDescription();
    }
    
    /**
     * 具体装饰者:摩卡
     */
    class Mocha extends CondimentDerector {
    
        /**
         * 保留基类的引用,以便于组合装饰者行为
         */
        Beverage beverage;
    
        public Mocha(Beverage beverage) {
            this.beverage = beverage;
        }
    
        @Override
        public double cost() {
            return beverage.cost() + 2;
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription() + ",monka";
        }
    }
    
    /**
     * 具体装饰者:豆浆
     */
    class Soy extends CondimentDerector {
    
        Beverage beverage;
    
        public Soy(Beverage beverage) {
            this.beverage = beverage;
        }
    
        @Override
        public double cost() {
            return beverage.cost() + 3;
        }
    
        @Override
        public String getDescription() {
            return beverage.getDescription() + "soy";
        }
    }
    
    /**
     * 调料A
     */
    class APart extends Beverage {
    
        public APart() {
            description = "Apart";
        }
    
        @Override
        public double cost() {
            return 19.5;
        }
    }
    
    /**
     * 调料B
     */
    class BPart extends Beverage {
    
        public BPart() {
            description = "Bpart";
        }
    
        @Override
        public double cost() {
            return 20.5;
        }
    }
    
    /**
     * 调料C
     */
    class CPart extends Beverage {
    
        public CPart() {
            description = "Cpart";
        }
    
        @Override
        public double cost() {
            return 21.5;
        }
    }
    
    /**
     * 调料D
     */
    class DPart extends Beverage {
    
        public DPart() {
            description = "Dpart";
        }
    
        @Override
        public double cost() {
            return 22.5;
        }
    }
  • 相关阅读:
    haproxy+keepalived配置haproxy反向代理的高可用
    正则表达式
    logstash 中multiline插件的用法
    logtash 接收多配置文件
    Debian 8 升级到 9 Debian 9 How to upgrade Debian 8 Jessie to Debian 9 Stretch
    YOLO object detection with OpenCV
    快速 图片颜色转换迁移 Color Transfer Opencv + Python
    对抗网络GAN的应用实例
    nvflash 报错解决
    卷积神经网络(CNN)在语音识别中的应用
  • 原文地址:https://www.cnblogs.com/ysw-go/p/10325870.html
Copyright © 2011-2022 走看看