Java设计模式-代理模式

来源:互联网 发布:php 处理图片 s3 编辑:程序博客网 时间:2024/04/29 11:42

概念

为其它对象提供一种代理以控制对这个对象的访问。

角色说明
这里写图片描述

Subject: 抽象主题类,声明真实主体与代理主题的共同接口方法。
RealSubject: 真实主题类,定义了真实对象的业务方法,供代理类来调用。
ProxySubject: 代理类,持有一个真实类的引用,在接口方法中调用真实主题(RealSubject)相应的方法。

实例

静态代理

1.创建subject(买车接口)

public interface IBuyCar {    void buyCar();}

2.创建RealSubject(一个买车客户)

public class Customer implements IBuyCar {    /**    * 购车款    */    private double mony;    public void setMony(int mony) {        this.mony= mony;    }    @Override    public void buyCar() {        Log.e("buyCar--->", "买这辆车总共花了" + mony+ "元");    }}

3.创建ProxySubject(4s店)

public class BuyCarProxy implements IBuyCar{/*** 真实买车客户(RealSubject)*/    private Customer customer;    public BuyCarProxy(Customer customer){        this.customer=customer;    }    @Override    public void buyCar() {    //实现为客户买车        customer.buyCar();    }}

4.创建client

public class Client {    public static void main(String[] args) {       Customer customer=new Customer();       customer.setMony(120000);       BuyCarProxy buyCarProxy=new BuyCarProxy(customer);       buyCarProxy.buyCar();    }}

上面是是一种静态代理,即在代码运行前,代理类的class编译文件就已经存在了。
动态代理是相反的,通过反射动态的生成代理者对象,即具体代理谁会在执行阶段决定。Java提供了一个便捷的动态代理接口InvocationHandler,动态代理类只要实现这个接口即可。

动态代理

public class DynamicProxy implements InvocationHandler {    private Object object;    public DynamicProxy (Object object) {        this.object = object;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {          Object result = method.invoke(object,args);        return result;    }}

客户端调用

public class Client {    public static void main(String[] args) {        //要代理的这真实对象        Customer customer = new Customer();        DynamicProxy proxy = new DynamicProxy(customer);        //通过(InvocationHandler)newProxyInstance动态创建代理对象        //参数1(handler.getClass().getClassLoader()):使用InvocationHandler的lassLoader对象来加载我们的代理对象        //参数2(customer.getClass().getInterfaces()):表示要代理的真实对象        IBuyCar buyCar = (IBuyCar) Proxy.newProxyInstance(handler.getClass().getClassLoader(), customer.getClass().getInterfaces(), handler);        buyCar.buyCar();     }}

小结

优点:
协调调用者和被调用者,降低系统耦合度;
缺点:
其它设计模式的通病:增加了类,比直接调用原始对象多了一个中间者,会让结构稍显复杂。

使用场景

当一个对象不能或者不想直接访问另一个对象时,可以通过一个代理对象来间接访问。为保证客户端使用的透明性,委托对象和代理对象要实现同样的接口。
被访问的对象不想暴露全部内容时,可以通过代理去掉不想被访问的内容。