设计模式(十三)代理模式

作者: 我犟不过你 | 来源:发表于2021-01-12 11:01 被阅读0次

    1、概述

    代理模式是一种结构型设计模式, 让你能够提供对象的替代品或其占位符。 代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。

    2、适用场景

    1)远程代理

    在不同的地址空间运行的远程对象。本地代表对象的方法调用远程对象。

    2)虚拟代理

    延迟初始化 (虚拟代理)。 如果你有一个偶尔使用的重量级服务对象, 一直保持该对象运行会消耗系统资源时, 可使用代理模式。你无需在程序启动时就创建该对象, 可将对象的初始化延迟到真正有需要的时候。

    3)保护代理(安全代理)

    访问控制 , 如果你只希望特定客户端使用服务对象, 而客户端则是各种已启动的程序 (包括恶意程序), 此时可使用代理模式。代理可仅在客户端凭据满足要求时将请求传递给服务对象。

    4)智能指引

    可在没有客户端使用某个重量级对象时立即销毁该对象。代理会将所有获取了指向服务对象或其结果的客户端记录在案。 代理会时不时地遍历各个客户端, 检查它们是否仍在运行。 如果相应的客户端列表为空, 代理就会销毁该服务对象, 释放底层系统资源。

    3、实例

    有以下场景:

    小明和小雪是同班同学。
    这天小明拿着花过来,说是同学小王送给小雪的。
    第二天小明又拿着巧克力,还说是小王送给小雪的。
    之后又同样的送了娃娃。
    
    代理模式实现。
    

    创建送礼物接口:

    /**
     * 送礼物接口
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public interface ISendGifts {
    
        /**
         * 送花
         */
        void sendFlower();
    
        /**
         * 送巧克力
         */
        void sendChocolate();
    
        /**
         * 送娃娃
         */
        void sendDolls();
    }
    

    创建小雪:

    /**
     * 小雪
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public class XiaoXue {
    
        private String name;
    
        public XiaoXue(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    创建小明(代理):

    /**
     * 小明
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public class XiaoMing implements ISendGifts {
    
        private XiaoWang xiaoWang;
    
        public XiaoWang getXiaoWang() {
            return xiaoWang;
        }
    
        public void setXiaoWang(XiaoWang xiaoWang) {
            this.xiaoWang = xiaoWang;
        }
    
        public XiaoMing(XiaoXue xiaoxue) {
            this.xiaoWang = new XiaoWang(xiaoxue);
        }
    
        @Override
        public void sendFlower() {
            xiaoWang.sendFlower();
        }
    
        @Override
        public void sendChocolate() {
            xiaoWang.sendChocolate();
        }
    
        @Override
        public void sendDolls() {
            xiaoWang.sendDolls();
        }
    }
    

    创建小王:

    /**
     * 小王
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public class XiaoWang implements ISendGifts{
    
        private XiaoXue xiaoXue;
    
        public XiaoWang(XiaoXue xiaoXue) {
            this.xiaoXue = xiaoXue;
        }
    
        @Override
        public void sendFlower() {
            System.out.println(xiaoXue.getName() + ",我是小王,送你一朵小红花");
        }
    
        @Override
        public void sendChocolate() {
            System.out.println(xiaoXue.getName() + ",我是小王,送你一块巧克力");
        }
    
        @Override
        public void sendDolls() {
            System.out.println(xiaoXue.getName() + ",我是小王,送你一个洋娃娃");
        }
    }
    

    创建测试类:

    /**
     * 测试类
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public class TestDemo {
    
        public static void main(String[] args) {
            XiaoXue xiaoXue = new XiaoXue("小雪");
            XiaoMing xiaoMing = new XiaoMing(xiaoXue);
            xiaoMing.sendFlower();
            xiaoMing.sendChocolate();
            xiaoMing.sendDolls();
        }
    }
    

    结果:

    小雪,我是小王,送你一朵小红花
    小雪,我是小王,送你一块巧克力
    小雪,我是小王,送你一个洋娃娃
    

    4、分析

    上面代码达到了小明代替小王送礼物给小雪的过程,代码结构如下


    类关系

    代理逻辑如下图:

    代理

    5、总结

    优点:
    1)你可以在客户端毫无察觉的情况下控制服务对象。
    2)如果客户端对服务对象的生命周期没有特殊要求, 你可以对生命周期进行管理。
    3)即使服务对象还未准备好或不存在, 代理也可以正常工作。
    4)开闭原则。 你可以在不对服务或客户端做出修改的情况下创建新代理。
    缺点:
    1)代码复杂
    2)增加响应的延时

    相关文章

      网友评论

        本文标题:设计模式(十三)代理模式

        本文链接:https://www.haomeiwen.com/subject/obgloktx.html