• 代理模式


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

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

    结构如图:

    代码如下:

    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;
        }
    
    }
  • 相关阅读:
    poj 1789 Truck History(最小生成树)
    POJ 3096 Surprising Strings(STL map string set vector)
    hdu 1412 (STL list)
    POJ 1552 Doubles (C++ STL set使用)
    poj 水题系列
    洛谷P4859 已经没有什么好害怕的了
    CF1228E Another Filling the Grid
    二项式反演
    AT [ABC177F] I hate Shortest Path Problem
    [NOI2020]制作菜品
  • 原文地址:https://www.cnblogs.com/SasaL/p/10655681.html
Copyright © 2020-2023  润新知