设计模式学习-代理模式

2019-08-07  本文已影响0人  m1Ku

定义

代理模式又称为委托模式,它可以为其他对象提供一种代理以控制对这个对象的访问。我们可以通过代理对象间接访问被代理对象,代理对象和被代理对象需要实现相同的接口。代理模式在生活中很常用,比如外卖员帮我们送餐,律师帮我们打官司,或者是银行大堂经理帮我们办业务,都是代理模式的实现。

UML类图

代理模式

代理模式的角色

示例

静态代理

静态代理需要自行定义代理对象,这里以去银行办理业务为例,抽象出申请卡和注销卡操作为IBank接口。

/**
 * 定义委托类和代理类共同的接口方法(接口或者抽象类)
 * 相当于是委托类和代理类行为的抽象
 */
public interface IBank {
     void applyCard();
     void cancelCard();
}

定义委托类和代理类

/**
 * 委托类,执行具体的业务逻辑方法
 */
public class Man implements IBank {
    @Override
    public void applyCard() {
        System.out.println("客户填单,申请办卡");
    }

    @Override
    public void cancelCard() {
        System.out.println("客户填单,申请挂失");
    }
}
/**
 * 代理类,该类持有委托类的引用,在其实现的方法中调用委托类中
 * 相应的接口方法执行,起到代理的作用
 */
public class BankManager implements IBank {

    private IBank man;

    /**
     * 构造方法中传入委托类
     * @param man
     */
    public BankManager(IBank man){
        this.man = man;
    }

    @Override
    public void applyCard() {
        System.out.println("银行经理,问询客户需求");
        //调用委托类对应的接口方法
        man.applyCard();
        System.out.println("欢送客户");
    }

    @Override
    public void cancelCard() {
        System.out.println("银行经理,问询客户需求");
        man.cancelCard();
        System.out.println("欢送客户");
    }
}

在客户端实例化委托类,并将其传入代理类,调用代理方法

public class Client {
    public static void main(String []args){
        Man man = new Man();
        //将委托类传入代理类
        BankManager manager = new BankManager(man);
        //调用代理类的接口方法
        manager.applyCard();
        manager.cancelCard();
    }
}

动态代理

相对于静态代理,动态代理在编码阶段不需要编写代理类,而是通过反射机制动态的生成代理者的对象的,Java提供了InvocationHandler接口,通过实现该接口可以完成动态代理,具体实现如下,还是代理Man对象。

   /**
     * 实现InvocationHandler接口,构造方法中传入委托类
     * invoke方法中调用委托类的方法
     */
    public static class BankInvocationHandler implements InvocationHandler{
        private Man man;
        public BankInvocationHandler(Man man){
            this.man = man;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("接待客户");
            Object object = method.invoke(man,args);
            System.out.println("欢送客户");
            return object;
        }
    }
public class Client {
    public static void main(String[]args){

        Man man = new Man();
        //调用newProxyInstance方法获得代理类
        IBank proxy = (IBank) Proxy.newProxyInstance(
                IBank.class.getClassLoader(),
                new Class<?>[]{IBank.class},
                new BankInvocationHandler(man)
        );
        //调用代理类的方法
        proxy.applyCard();
        proxy.cancelCard();
    }

调用代理类的方法时,会执行到InvocationHandler的invoke方法,在这个方法中又调用了委托类对应的方法,可以添加我们自己的逻辑,这就完成了对Men对象的代理。

Android源码中的代理模式

Retrofit网络请求框架就是使用了动态代理的方式,代理了网络请求接口完成的网络请求。具体Retrofit源码分析看Android源码学习-Retrofit源码浅析

上一篇下一篇

猜你喜欢

热点阅读