代理模式(包装对象,来控制对此对象的访问)

源码地址 https://github.com/DingMouRen/DesignPattern
代理模式(包装对象,来控制对此对象的访问)_第1张图片
代理模式.png
  • Subject抽象主题类,主要负责声明真实主题与代理的共同接口方法,该类既可以是一个抽象类,也可以是一个接口。
  • RealSubject真实主题类,也就是被代理的类,定义了代理所表示的真实对象,由其执行具体业务逻辑方法,可客户端则通过代理类间接地调用真实主题类中定义的方法
  • ProxySubject代理类,持有一个对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行,从而起到代理的作用。
定义

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

使用场景

  • 远程代理。为一个对象在不同地址空间提供局部代表
  • 虚代理。根据需要创建开销很大的对象。
  • 保护代理。控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
  • 智能指引。取代简单的指针,它在访问对象时执行一些附加操作。
协作

代理根据其种类,在适当的时候向RealSubject转发请求。

举个栗子

假设我们要进行诉讼,分为提交申请、进行举证、开始辩护和诉讼完成。通常的做法就是找一个专业的律师,帮我们操办。这里有两种方式:静态代理和动态代理。动态代理:通过反射机制动态的生成代理者对象。

//主题抽象接口:诉讼流程
public interface ILawsuit {
    //提交申请
    void submit();
    //进行举证
    void burden();
    //开始辩护
    void defend();
    //诉讼完成
    void finish();
}
//被代理的类
public class PersonA implements ILawsuit {
    @Override
    public void submit() {
        System.out.println(getClass().getSimpleName()+"提交仲裁申请");
    }

    @Override
    public void burden() {
        System.out.println(getClass().getSimpleName()+"进行举证");
    }

    @Override
    public void defend() {
        System.out.println(getClass().getSimpleName()+"进行辩护");
    }

    @Override
    public void finish() {
        System.out.println(getClass().getSimpleName()+"诉讼成功");
    }
}
//静态代理类
public class Lawer implements ILawsuit {
    private ILawsuit person;//持有一个具体被代理者的引用

    public Lawer(ILawsuit person) {
        this.person = person;
    }

    @Override
    public void submit() {
        person.submit();
    }

    @Override
    public void burden() {
        person.burden();
    }

    @Override
    public void defend() {
        person.defend();
    }

    @Override
    public void finish() {
        person.finish();
    }
}

//动态代理类:通过反射机制动态地生成代理者的对象
public class DynamicProxy implements InvocationHandler {
    private Object obj;//被代理类的引用

    public DynamicProxy(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //调用被代理类对象的方法
        Object result = method.invoke(obj,args);
        return result;
    }
}

使用
    public static void main(String[] args) {
        /**
         * 静态代理
         */
        //构造一个要诉讼的公民
        PersonA personA = new PersonA();
        //公民找到律师
        Lawer lawer = new Lawer(personA);
        //律师完全代理诉讼的整个过程
        System.out.println("静态代理");
        lawer.submit();
        lawer.burden();
        lawer.defend();
        lawer.finish();

        /**
         * 动态代理
         */
        ILawsuit personB = new PersonB();
        DynamicProxy dynamicProxy = new DynamicProxy(personB);
        ClassLoader classLoader = personB.getClass().getClassLoader();
        ILawsuit lawsuit = (ILawsuit) Proxy.newProxyInstance(classLoader,new Class[]{ILawsuit.class},dynamicProxy);

        System.out.println("\n动态代理");
        lawsuit.submit();
        lawsuit.burden();
        lawsuit.defend();
        lawsuit.finish();
    }

你可能感兴趣的:(代理模式(包装对象,来控制对此对象的访问))