• 装饰器模式


    装饰器模式(Decorator Pattern)

    定义

    也叫包装模式 (Wrapper Pattern)
    是指在不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的替代方案。
    属于结构型模式

    适用场景

    1. 适用于扩展一个类的功能或给一个类添加附加职责。
    2. 动态的给一个对象添加功能,这些功能可以再动态的撤销。
    3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,使用继承关系将变得非常复杂。

    标准示例

    在这里插入图片描述
    Component 是一个最顶层的抽象组件。
    其他都是Component的子类。
    ConcreteComponent 是一个具体的组件,是默认的标配。
    Decorator 是一个抽象的装饰器,让用户可以对其扩展定制。
    ConcreteDecoratorA、ConcreteDecoratorB 就是两个具体的装饰类。

    上述类图中具体代码如下:
    Component

    public abstract class Component {
        public abstract void operation();
    }
    

    Decorator

    public abstract class Decorator extends Component{
        //持有组件对象
        protected Component component;
    
        /**
         * 构造方法,传入组件对象
         * @param component
         */
        public Decorator(Component component){
            this.component = component;
        }
        public void operation() {
            //转发请求给组件对象,可以在转发前后执行一些附加动作
            component.operation();
        }
    }
    

    ConcreteComponent

    public class ConcreteComponent extends Component{
    
        public void operation() {
            System.out.println("默认标准输出");
        }
    }
    

    ConcreteDecoratorA

    public class ConcreteDecoratorA extends Decorator{
    
        public ConcreteDecoratorA(Component component) {
            super(component);
        }
    
        private void operationOne(){
            System.out.println("A ~ one ~");
        }
        private void operationTwo(){
            System.out.println("A ~ two ~");}
    
        @Override
        public void operation() {
            //调用父类方法,可以在调用前后执行一些附加动作
            operationOne();
            super.operation();
            operationTwo();
        }
    }
    

    ConcreteDecoratorB

    public class ConcreteDecoratorB extends Decorator{
        
        public ConcreteDecoratorB(Component component) {
            super(component);
        }
    
        private void operationOne(){
            System.out.println("B ~ one ~");
        }
        private void operationTwo(){
            System.out.println("B ~ two ~");}
    
        @Override
        public void operation() {
            //调用父类方法,可以在调用前后执行一些附加动作
            operationOne();
            super.operation();
            operationTwo();
        }
    }
    

    以上是相关类,Client中展示了使用方法:

    public class Client {
        public static void main(String[] args) {
        	//首先定义一个 “默认标准”
            Component c1 = new ConcreteComponent();
            //在默认基础上,包装上decoratorA的逻辑
            Decorator decoratorA = new ConcreteDecoratorA(c1);
            //执行包装过A的operation方法,输出见<1>
            decoratorA.operation();
            //在默认基础上,包装上B的逻辑
            Decorator decoratorB = new ConcreteDecoratorB(c1);
            //执行包装过B的operation方法,输出见<2>
            decoratorB.operation();
            //在B的基础上(B是基于默认标准的),包装上A的逻辑
            Decorator decoratorAB = new ConcreteDecoratorA(decoratorB);
            //执行A(B(c1))的operation方法,输出见<3>
            decoratorAB.operation();
        }
    }
    

    Client main方法的输出:
    输出<1>:A包裹c1

    A ~ one ~
    默认标准输出
    A ~ two ~

    输出<2>:B包裹c1

    B ~ one ~
    默认标准输出
    B ~ two ~

    输出<3>:B包裹c1,A包裹B

    A ~ one ~
    B ~ one ~
    默认标准输出
    B ~ two ~
    A ~ two ~


    装饰器模式可以达到上述层层装饰的效果,可以在不改变默认标准实现的前提下,通过层层包裹逻辑,增加其功能。
    下面再举个实际场景的例子。

    电商平台购物时,我们总会看到一些商品这样的销售策略,基础版一个价格,在基础版上叠加更多的功能/配置,并通过赠送的辅助产品不同,设置成不同的套餐,每个套餐价格也各异,丰俭由人。
    我们以笔记本电脑为例:
    基础版为:一部笔记本电脑,3699元
    超值版为:一部笔记本电脑+高端电脑包+品牌鼠标,3999元
    豪华版为:一部笔记本电脑+高端电脑包+品牌鼠标+外接键盘+笔记本支架+USB扩展坞,4299元

    我们有这样几个类:
    INoteBookPackage 笔记本套餐抽象类;(相当于 Component )
    BasicPackage,基础套餐(相当于 ConcreteComponent )
    SuperValuePackageDecorator,超值套餐;(相当于ConcreteDecoratorA )
    LuxuryPackageDecorator,豪华套餐;(相当于ConcreteDecoratorB )
    Decorator,装饰器
    具体代码如下:
    INoteBookPackage

    public abstract class INoteBookPackage {
        protected abstract String getConfigMsg();
        protected abstract int getConfigPrice();
    }
    

    BasicPackage

    public class BasicPackage extends INoteBookPackage{
        public String getConfigMsg() {
            return "一台笔记本";
        }
    
        public int getConfigPrice() {
            return 3699;
        }
    }
    

    Decorator

    public abstract class Decorator extends INoteBookPackage{
    
        private INoteBookPackage noteBookPackage;
    
        public Decorator(INoteBookPackage noteBookPackage){
            this.noteBookPackage = noteBookPackage;
        }
    
        protected String getConfigMsg() {
            return noteBookPackage.getConfigMsg();
        }
    
        protected int getConfigPrice() {
            return noteBookPackage.getConfigPrice();
        }
    }
    

    SuperValuePackageDecorator

    public class SuperValuePackageDecorator extends Decorator{
        public SuperValuePackageDecorator(INoteBookPackage noteBookPackage) {
            super(noteBookPackage);
        }
        @Override
        protected String getConfigMsg() {
            return super.getConfigMsg()+"+高端电脑包+品牌鼠标";
        }
        @Override
        protected int getConfigPrice() {
            return super.getConfigPrice()+300;
        }
    }
    

    LuxuryPackageDecorator

    public class LuxuryPackageDecorator extends Decorator{
        public LuxuryPackageDecorator(INoteBookPackage noteBookPackage) {
            super(noteBookPackage);
        }
        @Override
        protected String getConfigMsg() {
            return super.getConfigMsg()+"+外接键盘+笔记本支架+USB扩展坞";
        }
        @Override
        protected int getConfigPrice() {
            return super.getConfigPrice()+300;
        }
    }
    

    Client

    public class Client {
        public static void main(String[] args) {
            INoteBookPackage noteBookPackage = new BasicPackage();
            System.out.println("默认标配:"+noteBookPackage.getConfigMsg()+" 价格:" + noteBookPackage.getConfigPrice());
    
            Decorator superValuePackage = new SuperValuePackageDecorator(noteBookPackage);
            System.out.println("超值套餐:"+superValuePackage.getConfigMsg()+" 价格:"+superValuePackage.getConfigPrice());
    
            Decorator luxuryPackage = new LuxuryPackageDecorator(superValuePackage);
            System.out.println("豪华套餐:"+luxuryPackage.getConfigMsg()+" 价格:"+luxuryPackage.getConfigPrice());
        }
    }
    

    Client 的main执行结果为:

    默认标配:一台笔记本 价格:3699
    超值套餐:一台笔记本+高端电脑包+品牌鼠标 价格:3999
    豪华套餐:一台笔记本+高端电脑包+品牌鼠标+外接键盘+笔记本支架+USB扩展坞 价格:4299
    

    以上为本文全部内容,感谢阅读。

  • 相关阅读:
    Python多进程之分享(multiprocessing包)
    Linux系统的安装
    操作系统实验二、进程和线程管理(Windows 2学时)多线程创建
    亚像素源码
    CocosCreater 教程(下)
    CodeQL 的安装及基本使用
    Redis6.2.1版本集群新加副本
    Yolov5 转换成 RKNN模型
    Verilog中什么是断言?
    Kibana 中的身份验证-单点登录实现必读
  • 原文地址:https://blog.csdn.net/yuiezt/article/details/139808981