zoukankan      html  css  js  c++  java
  • 代理模式

    定义:为其他对象提供一种代理以控制对这个对象的访问。代理模式本质上也叫做委托模式,它是一种基本设计技巧,许多其他模式,比如状态模式,策略模式,访问者模式本质上是在特殊场合采用了委托模式。代理模式应用非常广泛,下面举出一个通用示例,假设现有三个角色,抽象主题、具体实现主题、代理主题:

    //抽象主题类
    public interface Subject{
        public void request();
    }
    //真实主题类
    public class RealSubject implements Subject{
        //实现方法
        public void request(){
        }
    }
    //代理类
    public class Proxy implements Subject{
        //要代理实现哪个类
        private Subject subject = null;
        //默认代理者
        public Proxy(){
            this.subject = new Proxy();
        }
        //通过构造函数传递代理类    
        public Proxy(Object... objects){
            
        }
        //实现接口中定义的方法
        public void request(){
            this.before();
            this.subject.request();
            this.after();
        }
        //预处理
        private void before(){
        }
        //后处理
        private void after(){
        }
    }

    代理模式有如下优点:

    • 职责清晰。真实的角色就是实现实际的业务逻辑,不用关心其他非本职的事务。
    • 高扩展性。具体主题角色是随时都会发生变化的,但只要他实现了接口,不管如何变化,都不会影响到代理类的使用
    • 智能化。比如动态代理

    代理模式扩展:

      上述通用代码是普通代理,还可以改造为强制代理模式,也就是不允许直接new具体对象,必须通过代理产生;还有一种是个性化代理,一个类可以实现多个接口,完成不同任务的整合,代理的目的是在目标对象方法的基础上进行增强,这种增强本质上通常是拦截和过滤目标方法,只需要在普通代理类上实现更多接口即可实现;最后但很重要的一种就是动态代理,什么是动态代理?就是在实现阶段不用关心代理谁,只在运行阶段才指定代理哪个对象。相对而言,自己写代理类就是静态代理。现在非常常见的面向横切面编程,也就是AOP,其核心就是动态代理机制。

      提到动态代理,必须说下jdk提供的一个动态代理接口:InvocationHandler,通过这个接口,所有的方法都由该handler来处理,由它接管所有实际的处理任务。下面看一个动态代理通用编程模型,

      先看Subject接口,抽象主题类:

    public interface Subject{
        //业务操作
        public void doSomething(String str);
    }

      实现主题类:

    //真实主题类
    public class RealSubject implements Subject{
        //业务操作
        public void doSomething(String str){
        }
    }

      重点的动态代理类:

    //动态代理的Handler类
    public
    class MyInvocationHandler implements InvocationHandler{ //被代理的对象 private Object target = null; //传递一个对象 public MyInvocationHandler(Object _obj){ this.target = _obj; } //代理方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwble{   return method.invoke(this.target, args); } }

      所有通过动态代理实现的全部通过invoke()方法调用。动态代理:

    public class DynamicProxy<T>{
        public static <T> T newProxyInstance(ClassLoader loader,Class<?> interfaces,  InvocationHandler h){
        //寻找JoinPoint连接点,AOP框架使用元数据定义
        if(true){
            //执行一个前置通知
            (new BeforeAdvice()).exec();
        }
        return (T)Proxy.newProxyInstance(loader, interfaces, h);
    }
    public interface IAdvice{
        public void exec();
    }
    public class BeforeAdvice implements IAdvice{
        public void exec(){
        }
    }
    //场景调用
    public class Client{
        public static void main(String[] args){
            Subject subject = new RealSubject();
            //定义一个handler
            InvocationHandler hander = new MyInvocationHandle(subject);
            //定义主题的代理
            Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass(),handler);
            proxy.doSomething("ok");
    }

      在DynamicProxy类中,有这样的方法,

        Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass(),handler); 
     该方法重新生成了一个对象,因为要使用代理!注意getInterfaces()这句话,查找所有该类的接口,然后实现接口中所有方法,当然,都是空方法,由谁来具体实现呢?
    就是MyInvocationHandle这个对象。于是我们知道了,由
    InvocationHandler实现接口中所有方法,由其invoke具体接管所有方法的实现。
  • 相关阅读:
    SCP 命令
    linux下IPTABLES配置详解
    Linux rpm 命令参数使用详解
    Linux(Centos7)yum安装最新redis
    YUM常用命令介绍
    Centos7下Yum安装PHP5.5,5.6,7.0
    腾讯云CentOS7.0使用yum安装mysql
    如何在CentOS 6.5上升级PHP
    第一个Python程序
    Python简介及环境部署
  • 原文地址:https://www.cnblogs.com/loveBolin/p/9697041.html
Copyright © 2011-2022 走看看