zoukankan      html  css  js  c++  java
  • 设计模式2

    装饰者模式 : 在不改变原有对象的基础上附加功能,动态的给一个对象添加或者撤销功能 (通过调用super的方法控制执行的顺序),相比生成子类更灵活。

    1.装饰者模式应用场景

    Java IO流,Mybatis的缓存框架,Spring中的Session等等。

    2.装饰者模式优缺点

    优点:可以不改变原有对象的情况下动态扩展功能,可以使扩展的多个功能按想要的顺序执行,以实现不同效果。

    缺点:更多的类,使程序复杂

    3.装饰者模式定义

    (1)抽象组件:定义一个抽象接口(或者抽象类),来规范准备附加功能的类

    (2)具体组件:将要被附加功能的类,实现抽象构件角色接口

    (3)抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口

    (4)具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。

    说完装饰者的特点后,我这边写个案例帮助大家理解装饰器模式在实际项目种如何运用

    案例:  在原有的网关功能基础上扩展新功能

    需求分析:网关接口原来的功能,主要是解析数据,对部分数据做脱敏处理,随着业务的发展现在需要在原来功能的基础上扩展新的功能,包括接口的限流操作,接口日志的收集

    通过装饰器模式的改造类图的变化如下 

     

    代码实现部分

    1.定义一个抽象类(原来的代码)

    package com.brian.decorative.service;
    
    /**
     * @program: architect
     * @author: Brian Huang
     * @create: 2019-05-14 21:08
     **/
    public abstract class BaseGateway {
    
        public abstract void service();
    }

    2.定义被装饰角色 (原来的代码)

    package com.brian.decorative.service.impl;
    
    import com.brian.decorative.service.BaseGateway;
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * @program: architect
     * @author: Brian Huang
     * @create: 2019-05-14 21:15
     **/
    @Slf4j
    public class DesensitizationComponent  extends BaseGateway {
    
        @Override
        public void service() {
            log.info("1-->>> 网关中获取基本的操作,数据脱敏...");
        }
    }

    3.定义抽象装饰角色 (扩展的代码)

    package com.brian.decorative.service;
    
    /**
     * @program: architect
     * @author: Brian Huang
     * @create: 2019-05-14 21:13
     **/
    public abstract class GatewayDecorate extends BaseGateway {
    
        private BaseGateway baseGateway;
    
        public GatewayDecorate(BaseGateway baseGateway) {
            this.baseGateway = baseGateway;
        }
    
        @Override
        public void service() {
            if(baseGateway !=null){
                baseGateway.service();
            }
        }
    }

    4.定义具体装饰角色(扩展的代码)

    package com.brian.decorative.service.impl;
    
    import com.brian.decorative.service.BaseGateway;
    import com.brian.decorative.service.GatewayDecorate;
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * @program: architect
     * @author: Brian Huang
     * @create: 2019-05-14 21:16
     **/
    @Slf4j
    public class LimitComponent extends GatewayDecorate {
    
        public LimitComponent(BaseGateway baseGateway) {
            super(baseGateway);
        }
    
        @Override
        public void service() {
            super.service();
            log.info("3-->>> 网关中新增API接口的限流..");
        }
    }
    
    
    
    ----------
    
    
    package com.brian.decorative.service.impl;
    
    import com.brian.decorative.service.BaseGateway;
    import com.brian.decorative.service.GatewayDecorate;
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * @program: architect
     * @author: Brian Huang
     * @create: 2019-05-14 21:16
     **/
    @Slf4j
    public class LogComponent  extends GatewayDecorate {
    
        public LogComponent(BaseGateway baseGateway) {
            super(baseGateway);
        }
    
        @Override
        public void service() {
            super.service();
            log.info("2-->>> 网关中新增日志收集..");
        }
    }

    5.使用工厂获取装饰类(扩展的代码)

    package com.brian.decorative.factory;
    
    import com.brian.decorative.service.BaseGateway;
    import com.brian.decorative.service.impl.DesensitizationComponent;
    import com.brian.decorative.service.impl.LimitComponent;
    import com.brian.decorative.service.impl.LogComponent;
    
    /**
     * @program: architect
     * @author: Brian Huang
     * @create: 2019-05-14 21:38
     **/
    public class FactoryGateway {
    
        public static BaseGateway getBaseGateway() {
            return new LimitComponent(new LogComponent(new DesensitizationComponent()));
        }
    
    
        public static void main(String[] args) {
            FactoryGateway.getBaseGateway().service();
        }
    }

    测试结果:

    责任链与装饰模式区别:
    1.责任链模式下,每个被调用者都持有下一个被调用者的引用,客户端只需要发起一次调用即可,整个过程是链式的调用,从前往后执行。
    2.装饰者模式下,持有被装饰的对象,并具备被装饰者的行为,对其行为进行补充增强,整个过程是像包裹住的洋葱,从内层一层向外调用。

    装饰器与适配器的区别:
    其实适配器模式也是一种包装(Wrapper)模式,它们看似都是起到包装一个类或对象的作用,但是它们使用的目的非常不一样:
    1、适配器模式的意义是要将一个接口转变成另外一个接口,它的目的是通过改变接口来达到重复使用的目的
    2、装饰器模式不要改变被装饰对象的接口,而是恰恰要保持原有的借口哦,但是增强原有接口的功能,或者改变元有对象的处理方法而提升性能

     博客参考:https://www.cnblogs.com/xrq730/p/4908940.html

  • 相关阅读:
    心情日记:【原创诗歌】怆情吟
    心情日记:2008年3月3日 奶奶去世
    心情日记:健身日记
    金融基础概念期货
    FXDD点值获利计算
    外汇基础概念汇率
    报告论文:是学生都copy下来,现在不用,将来绝对要用(转)
    情感日记:毕业临走物语
    美元为什么坚挺
    英特尔首席技术官:人机智能鸿沟将于2050年消失
  • 原文地址:https://www.cnblogs.com/hlkawa/p/13263635.html
Copyright © 2011-2022 走看看