美文网首页
代理模式

代理模式

作者: nieniemin | 来源:发表于2020-06-22 22:48 被阅读0次

    什么是代理模式

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

    模式角色

    抽象角色(MovieStar)
    通过接口或抽象类声明真实角色实现的业务方法。

    真实角色(BaoQiangStar)
    实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用

    代理角色(AgentProxy)
    实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作

    UML类图

    代理模式

    代码实现

    现实世界中有很多代理场景,比如租房。房东为真实租房角色,中介为房东代理租售业务。明星都有经纪人帮忙协调资源等等。
    静态代理实现:编辑代理类代码,实现代理模式;在编译期就生成了代理类。

    public interface MovieStar {
    
        public void movie();
    }
    
    public class BaoQiangStar implements MovieStar {
    
        @Override
        public void movie() {
            System.out.println("宝强出演电影.");
        }
    }
    
    public class AgentProxy implements MovieStar {
    
        private BaoQiangStar baoQiangStar;
    
        public  AgentProxy(BaoQiangStar baoQiangStar) {
            this.baoQiangStar = baoQiangStar;
        }
    
        public void contract() {
            System.out.println("宝强出演电影前,经纪人先签合同.");
        }
    
        @Override
        public void movie() {
            contract();
            baoQiangStar.movie();
        }
    
    }
    
    public class Client {
        public static void main(String[] args) {
            BaoQiangStar baoQiangStar = new BaoQiangStar();
            AgentProxy agentProxy = new AgentProxy(baoQiangStar);
            agentProxy.movie();
        }
    }
    

    动态代理:代理类在程序运行时创建的代理方式被称为动态代理。也就是说,代理类并不需要在Java代码中定义,而是在运行时动态生成的。基于 JDK 实现动态代理,通过jdk提供的工具方法Proxy.newProxyInstance动态构建全新的代理类(继承Proxy类,并持有InvocationHandler接口引用 )字节码文件并实例化对象返回。(jdk动态代理是由java内部的反射机制来实例化代理对象,并代理的调用委托类方法)
    抽象角色和真实角色不做修改,代理类角色不再和真实角色一样实现抽象角色而是实现InvocationHandler。

    public class DynamicProxyHandler implements InvocationHandler {
    
        private Object target;
    
        public DynamicProxyHandler(Object target) {
            this.target = target;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("jdk动态代理.....");
            Object o = method.invoke(target, args);
            
            return o;
        }
    }
    
    public class Client {
    
        public static void main(String[] args) {
            BaoQiangStar baoQiangStar = new BaoQiangStar();
            InvocationHandler invocationHandler = new DynamicProxyHandler(baoQiangStar);
            // 参数1:指定当前目标对象使用的类加载器
            // 参数2:指定要被代理类的接口
            // 参数3:执行目标对象方法时会触发事件处理方法。
            MovieStar movieStar = (MovieStar) Proxy.newProxyInstance(baoQiangStar.getClass().getClassLoader(), baoQiangStar.getClass().getInterfaces(), invocationHandler);
            movieStar.movie();
        }
    
    }
    

    优点

    实现了访问者与访问对象之间的解耦
    代理模式在客户端与对象之间起到中介作用,保护了对对象的访问
    代理模式可以在访问过程中增加逻辑(aop)

    缺点
    静态代理重用性不高,一百个明星(真实角色)就要有一百个经纪人(代理)。

    代理模式完整代码

    相关文章

      网友评论

          本文标题:代理模式

          本文链接:https://www.haomeiwen.com/subject/xslatktx.html