代理模式

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

这句话看起来有点不明白,个人的理解是代理隐藏了真实的对象,当需要调用真实对象时,通过代理来访问。

结构如图:

代码如下:

package cn.sasa.demo1;

public interface ISubject {
    
    void request();

}
package cn.sasa.demo1;

public class RealSubject implements ISubject{

    @Override
    public void request() {
        System.out.println("真实的请求");
    }

}
package cn.sasa.demo1;

//代理类
public class Proxy implements ISubject{

    RealSubject rsub;
    @Override
    public void request() {
        if(rsub == null) {
            rsub = new RealSubject();
        }
        rsub.request();
    }

}

客户端代码:

package cn.sasa.demo1;

public class Test {
    public static void main(String[] args) {
        Proxy pro = new Proxy();
        pro.request();
    }
}

可以理解为委托人(RealSubject)向代理人(Proxy)做委托,当需要寻找这个委托人的时候,找代理人就可以了。

书中形象的比喻为A代理B向C(目标对象)执行一些操作,代码如下:

package cn.sasa.demo;

//委托人和代理人的接口
public interface IAction {

    void action();

}
package cn.sasa.demo;

//委托人
public class Consigner implements IAction{

    //委托人知道委托的目标
    private Target tar;
    
    public Consigner(Target tar) {
        this.tar = tar;
    }
    
    @Override
    public void action() {
        if(tar != null) {
            System.out.println(tar.name + ",hi~");
        }
    }

}
package cn.sasa.demo;

//代理人
public class Proxy implements IAction{

    //代理人知道委托人
    private Consigner conser;
    
    //代理人知道要委托的目标
    public Proxy(Target tar) {
        this.conser = new Consigner(tar);
    }
    
    @Override
    public void action() {
        conser.action();
    }

}
package cn.sasa.demo;

//目标
public class Target {
    public String name;
}

客户端代码:

package cn.sasa.demo;

public class Test {

    public static void main(String[] args) {

        //目标对象
        Target tar = new Target();
        tar.name = "sa";
        
        //代理人
        Proxy pro = new Proxy(tar);
        pro.action();
    }

}

代理模式的应用场景:

1、远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。比如WebService.

2、虚拟代理,根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。这样就可以达到性能的最优化。

3、安全代理,用来控制真实对象的访问权限。

4、智能指引,指当调用真实对象时,代理处理另外一些事情。

代理模式其实就是在访问对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。

以上是静态代理

Java的动态代理是在运行时,动态生成代理对象。

package cn.sasa.Test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
        //动态代理:在运行时生成代理类java.lang.reflect.Proxy
        //loader:被代理的类的加载器
        //interfaces:被代理的类实现的接口
        //h:
        ISubject subject = (ISubject) Proxy.newProxyInstance(RealSubject.class.getClassLoader(),
                new Class[] {ISubject.class},
                new InvocationHandler() {
                    //这里的proxy不要用
                    //method:被代理的对象的方法
                    //args:被代理的对象的方法的参数
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //System.out.println("在调用前执行");
                        if(method.getName().equals("method3")) {
                            if(args != null) {
                                args[0] = ((int)args[0])*2;
                            }
                        }
                        Object obj = method.invoke(new RealSubject(), args);
                        //System.out.println("在调用后执行");
                        return obj;
                    }
                });
        
        subject.method1();
        System.out.println(subject.method2());
        System.out.println(subject.method3(10));
    }
}
package cn.sasa.Test;

public interface ISubject {

    public void method1();
    
    public String method2();
    
    public int method3(int x);
}
package cn.sasa.Test;

public class RealSubject implements ISubject{

    @Override
    public void method1() {
        System.out.println("method1 running......");
    }

    @Override
    public String method2() {
        return "hahaha";
    }

    @Override
    public int method3(int x ){
        return x*2;
    }

}
原文地址:https://www.cnblogs.com/SasaL/p/10655681.html