代理模式

2019/09/20 设计模式 共 1585 字,约 5 分钟

代理模式

HeadFirst里面讲代理模式举了一个自动售卖机的例子,这本书用来理解设计模式可以说是非常棒的了,但是我看的不是特别明白……

定义

Provide a surrogate or placeholder for another object to control access to it.
为其他对象提供一种代理以控制对这个对象的访问。

类图

图片来自网络

代理模式类图

角色结构

Subject抽象主题角色:抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。
RealSubject具体主题角色:也叫做被委托角色、被代理角色。它才是冤大头,是业务逻辑的具体执行者。
Proxy代理主题角色:也叫做委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。

实例

最近要租房子,遇到这么一个情况:接到自如客服的电话,问我希望在哪里租房子,然后介绍给我一个负责这块区域的人,然后让他帮我找房子……
在这个例子中,自如客服就是代理主题角色,他帮我找到具体的主体角色——负责某块区域的中介,每个中介都需要实现或继承抽象主题角色。

  1. 创建抽象主题角色(抽象类或者接口),客服
public interface Subject {

    /**
     * 普通业务方法,找房子
     */
    void request();
}

  1. 具体主题角色,即负责某区域房源的中介。
public class RealSubject implements Subject {
    /**
     * 普通业务方法,找房子
     */
    @Override
    public void request() {
        System.out.println("帮我找到杭州某某A区域的房子租…");
    }
}

  1. 代理主题角色
public class Proxy implements Subject {

    /**
     * 要代理的类
     */
    private Subject subject;

    /**
     * 默认代理的类
     */
    public Proxy() {
        this.subject = new RealSubject();
    }

    /**
     * 通过构造函数指定代理类
     * @param subject
     */
    public Proxy(Subject subject) {
        this.subject = subject;
    }

    /**
     * 普通业务方法,找房子
     */
    @Override
    public void request() {
        this.before();
        this.subject.request();
        this.after();
    }

    /**
     * 预处理
     */
    private void before(){
        System.out.println("预处理的业务...");
    }

    /**
     * 善后处理
     */
    private void after(){
        System.out.println("执行完业务后的善后业务...");
    }
}

  1. 创建测试类
public class Test {

    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.request();
    }
}
  • 测试结果为
预处理的业务...
帮我找到杭州某某A区域的房子租…
执行完业务后的善后业务...

代理模式的优缺点

优点

  1. 职责清晰
    • 真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰。
  2. 高扩展性
    • 具体主题角色是随时都会发生变化的,只要它实现了接口,甭管它如何变化,都逃不脱如来佛的手掌(接口),那我们的代理类完全就可以在不做任何修改的情况下使用。
  3. 智能化
    • 这在我们以上的讲解中还没有体现出来,不过在我们以下的动态代理章节中你就会看到代理的智能化有兴趣的读者也可以看看Struts是如何把表单元素映射到对象上的。

使用场景

  1. 例如Spring AOP

源代码

GitHub地址

版权声明:本文为Planeswalker23所创,转载请带上原文链接,感谢。

文档信息

Search

    Table of Contents