zoukankan      html  css  js  c++  java
  • 【设计模式】结构型模式之代理模式

    1.模式动机与定义

    代理模式定义:为其他对象提供一种代理以控制对象的访问。

    2.模式结构与分析

    代理模式类图

    /**
     * 定义了RealSubject和Proxy的共同接口,使得在任何使用RealSubject的地方都可以使用Proxy
     */
    public interface Subject {
    ​
        void request();
    }
    
    /**
     * 定义了Proxy所代表的真正实体
     */
    public class RealSubject implements Subject {
    ​
        @Override
        public void request() {
            System.out.println("RealSubject invoke request() method");
        }
    }
    
    /**
     * 持有真实实体RealSubject的引用,使得Proxy可以访问真实实体
     * 并实现了Subject接口,这样代理就可以代替真实实体
     */
    public class Proxy implements Subject{
    ​
        private RealSubject subject;
    ​
        public Proxy() {
            this.subject = new RealSubject();
        }
    ​
        @Override
        public void request() {
            this.subject.request();
        }
    }
    
    public class Client {
    ​
        public static void main(String[] args) {
            Subject proxy = new Proxy();
            proxy.request();
        }
    }
    
    RealSubject invoke request() method
    

    3.模式实例与解析

    模式实例:
    学校里男同学A想要女同学B做自己的女朋友,想送女同学B礼物来追求女同学B,但是自己不好意思直接送,于是委托中间人来帮自己送礼物。

    /**
     * 校园中的漂亮女同学
     */
    public class SchoolGirl {
    ​
        private String name;
    ​
        public SchoolGirl(String name) {
            this.name = name;
        }
    ​
        public String getName() {
            return name;
        }
    ​
        public void setName(String name) {
            this.name = name;
        }
    }
    

    GiveGift接口对应于代理模式类图中的Subject。

    public interface GiveGift {
        void giveDolls();
        void giveFlowers();
        void giveChocolate();
    }
    

    下面的Pursuer对应于类图中的RealSubject,是真实实体对象。

    /**
     * 女同学的追求者
     */
    public class Pursuer implements GiveGift {
    ​
        private SchoolGirl girl;
    ​
        public Pursuer(SchoolGirl girl) {
            this.girl = girl;
        }
    ​
        @Override
        public void giveDolls() {
            System.out.println("[追求者]送给[" + this.girl.getName() + "]洋娃娃");
        }
    ​
        @Override
        public void giveFlowers() {
            System.out.println("[追求者]送给[" + this.girl.getName() + "]鲜花");
        }
    ​
        @Override
        public void giveChocolate() {
            System.out.println("[追求者]送给[" + this.girl.getName() + "]巧克力");
        }
    }
    

    Proxy对应于类图中的Proxy,为代理对象,其实现了与真实实体对象相同的接口GiveGift,并持有真实实体Pursuer实例的引用。

    /**
     * 女同学的追求者不好意思直接给女同学送礼物
     * 于是,追求者委托Proxy这个中间人来给女同学送礼物
     */
    public class Proxy implements GiveGift {
    ​
        private Pursuer pursuer;
    ​
        public Proxy(SchoolGirl girl) {
            this.pursuer = new Pursuer(girl);
        }
    ​
        @Override
        public void giveDolls() {
            this.pursuer.giveDolls();
        }
    ​
        @Override
        public void giveFlowers() {
            this.pursuer.giveFlowers();
        }
    ​
        @Override
        public void giveChocolate() {
            this.pursuer.giveChocolate();
        }
    }
    

    客户端代码如下。

    public class Client {
    ​
        public static void main(String[] args) {
            SchoolGirl girl = new SchoolGirl("小静");
            GiveGift proxy = new Proxy(girl);
            proxy.giveDolls();
            proxy.giveFlowers();
            proxy.giveChocolate();
        }
    }
    /**
     运行输出如下:
     [追求者]送给[小静]洋娃娃
     [追求者]送给[小静]鲜花
     [追求者]送给[小静]巧克力
     */
    

    4.模式效果与应用

    代理模式的使用场景如下
    1)远程代理。为一个对象在不同的地址空间提供局部代表,从而隐瞒一个对象存在于不同地址空间的事实。

    举例:在RPC调用中,会在client端创建一个server端接口的代理对象,这样client端调用远程server端的接口就像调用本地方法一样。

    2)虚拟代理。对象实例化需要花费很长时间,可以临时用虚拟代理代替。

    举例:我们访问一些网页时,常含有一些图片,如果图片很大,文本渲染完了,图片还没从服务器下载下来,这时,可以在网页上显示一个图片框,等到图片下载完了在显示真正的图片。

    3)安全代理。用于控制对象的访问权限。

    4)智能指引。调用真实的对象时,代理添加一些额外的操作。

    举例:Spring AOP。

    一句话总结:代理模式就是在访问对象时,引入了一定程度的间接性。

  • 相关阅读:
    MYSQL—— 基础入门,增、删、改、查(基础篇)
    作为测试你不可不知的iOS与Android差异点!
    MYSQL—— Insert的几种用法!
    mysql 使用Navicat Lite如何打开‘查询编辑器’,使用sql语句对表进行操作!
    mysql基础总结
    C#中的DllImport
    StructLayout特性
    c++中指针类型在c#中怎么对应?
    c++/java/c# 几种编程语言的指针、引用比较
    如何在C#中模拟C++的联合(Union)?[C#, C++] How To Simulate C++ Union In C#?
  • 原文地址:https://www.cnblogs.com/yeyang/p/10123965.html
Copyright © 2011-2022 走看看