结构型设计模式 — 代理模式

作者: Chase_stars | 来源:发表于2019-08-21 00:09 被阅读2次

把时间用在思考上是最能节省时间的事情。 — 卡曾斯

写在前面

本篇讲解代理模式,分静态代理动态代理两部分,由浅入深更好的理解代理模式。

代理模式又被称为委托模式,在现实生活中类似代理模式这种场景有很多,比如请律师打官司,代购,代理上网等。

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

代理模式.jpg

抽象主题类(Subject):声明真实主题与代理的公共的接口方法。
真实主题类(RealSubject):代理类所代表的真实主题,客户端通过代理类间接调用真实主题类的方法。
代理类(Proxy):持有对真实主题类的引用,在其所实现的接口方法中调用真实主题类相应的接口方法执行。

静态代理

通过一个例子来认识代理模式,我看好了一双球鞋,想托代购小芳帮我买,而我只需要给她钱就好,至于她怎么买去哪买我并不关心,最终能把鞋子送到我手里就好了。

我和代购小芳都具有"买"的行为,而代购小芳代替我去买,所以我和代购小芳不同的是代购小芳有买的过程,我却没有。

1.抽象主题类

我和代购小芳都具有“买”的行为,我是真实主题类,代购小芳是代理类,所以要声明真实主题与代理类的公共接口方法。

/**
 * 抽象主题类
 */
public interface Subject {
    
    void buy(String goods);
}
2.真实主题类

我才是真正要买这双鞋子的人,然而我也具有“买”的行为,所以我要实现抽象主题类,实现buy()方法。

/**
 * 真实主题类
 */
public class RealSubject implements Subject {
    @Override
    public void buy(String goods) {
        Log.d("RealSubject", "哈哈哈哈,好开心,我买到了喜欢的" + goods);
    }
}
3.代理类

代购小芳是帮我买,也具有“买”的行为,而且还要将买到的鞋子给我,所以代购小芳也要实现抽象主题类,实现buy()方法。

/**
 * 代理类
 */
public class Proxy implements Subject{

    private Subject mSubject;

    public Proxy(Subject subject) {
        mSubject = subject;
    }

    @Override
    public void buy(String goods) {
        // 代购小芳代替我买,买到后把鞋子给我
        mSubject.buy(goods);
    }
}
4.代购

现在就让代购小芳正式的帮我买鞋子了。

/**
 * 客户端
 */
public class Client {

    public Client() {
        // 这是我
        Subject realSubject = new RealSubject();
        // 将我作为参数实例化代购小芳
        Subject proxy = new Proxy(realSubject);
        // 代购小芳替我买球鞋了
        proxy.buy("好看的球鞋");
    }
}

动态代理

从上面静态代理的例子中可以看出,代购小芳只为我一个人买东西,这一趟代购不赔钱就谢天谢地了,代购小芳作为一名职业代购不可能只给我一个人买东西, 她还会帮许多人购买商品赚取利润。那么如何解决这个问题呢,动态代理横空出世了。

静态代理在编译期间就已经决定了代理谁,动态代理在编译期间不会决定代理谁,而是在代码运行时通过反射动态的生成代理类的对象,Java提供了动态代理的接口InvocationHandler,实现这个接口需要重写invoke()方法。

1.代理类

现在让我们来修改代理类,让代购小芳不只再为我自己买东西。

/**
 * 动态代理类
 */
public class InvocationProxy implements InvocationHandler {

    private Subject mSubject;

    public InvocationProxy(Subject subject) {
        mSubject = subject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Log.d("invoke", "成功购买到所需商品 = " + args[0]);
        return method.invoke(mSubject, args);
    }
}
2.代购

代购小芳现在不可以为我代购,还能为别人代购,那么先以为我代购为例,为其他人代购的实现方式也一样。

/**
 * 客户端
 */
public class InvocationClient {

    public InvocationClient() {
        // 这是我
        Subject realSubject = new RealSubject();
        // 创建动态代理类
        InvocationHandler proxy = new InvocationProxy(realSubject);
        // 调用Proxy.newProxyInstance()生成动态代理类
        Subject subject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), new Class[]{Subject.class}, proxy);
        subject.buy("好看的球鞋");
    }
}

总结

代理模式从编码角度来说分为静态代理和动态代理,从适用范围来说分为远程代理,虚拟代理,安全代理和智能指引四种类型,分别如下:

  • 远程代理:为一个对象在不同的地址空间提供局部代表,这样系统能够将Server部分的实现隐藏。
  • 虚拟代理:使用一个代理对象表示一个十分耗费资源的对象并在需要时创建。
  • 安全代理:用来控制真实对象访问时的权限,一般用于真实对象有不同的访问权限时。
  • 智能指引:当调用真实对象时,代理在处理另一些事情,比如计算真实对象的引用计数,当该对象没有引用时,可以自动释放它。或者访问一个实际对象时,检查是否已经能够锁定它,以确保其他的对象不能改变它。

代理模式的优点:

  • 真实主题类就是实现实际的业务逻辑,不用关心其他非本职工作。
  • 真实主题类随时都会发生变化,但是因为它实现了公共的接口,所以代理类可以不做任何修改就能够使用。

相关文章

  • 【设计模式】结构型设计模式汇总

    结构型设计模式汇总 结构型设计模式名称 结构型设计模式主要包括 7 大类: 代理模式 桥接模式 装饰器模式 适配器...

  • Android进阶之光——设计模式(结构型设计模式)

    结构型设计模式 结构型设计模式是从程序的结构上解决模块之间的耦合问题 代理模式 代理模式也被称为委托模式。 定义:...

  • spring框架中的设计模式二

    在这篇文章中,介绍4种设计模式。结构型设计模式:代理和复合模式。行为型设计模式:策略和模板方法模式。 代理模式 面...

  • 理解java的代理模式和动态代理

    代理模式 代理模式是23种设计模式之一,属于结构型模式。代理模式是最常见也是最常用的模式之一,只不过有很多设计模式...

  • Android设计模式——代理模式

    1.代理模式介绍 代理模式(Proxy Pattern),是七大结构型设计模式之一。 2.代理模式的定义 ...

  • 设计模式-代理模式

    代理模式介绍 代理模式(Proxy Pattern)也称为委托模式,是结构型设计模式的一种。在现实生活中用到代理的...

  • 设计模式-代理模式

    1.代理模式的介绍 代理模式(Proxy Pattern)也称为委托模式,是结构型设计模式的一种。在我们生活中代理...

  • 设计模式(六)代理模式

    1.代理模式简介 代理模式介绍 代理模式也叫委托模式,是结构型设计模式的一种。在现实生活中我们用到类似代理模式的场...

  • 代理模式——基础的设计

      代理模式(Proxy Pattern)也称委托模式(Delegate Pattern),是一种结构型设计模式,...

  • 设计模式之代理模式

    设计模式之代理模式 简介 代理模式是结构型设计模式。 当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过...

网友评论

    本文标题:结构型设计模式 — 代理模式

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