jasper的技术小窝

关注DevOps、运维监控、Python、Golang、开源、大数据、web开发、互联网

代理模式

作者:jasper | 分类:python | 标签:       | 阅读 1392 次 | 发布:2015-05-24 7:04 p.m.

代理模式其实就是多一个代理类出来,替原对象进行一些操作。代理对象可以在完成真实对象的功能的同时增加一些额外的动作,有些类似于我们现在的“代理点”或是“代理商”的作用。在java和python中又是怎样来分别实现代理模式的呢?

特别是在java中,一般分为静态代理和动态代理。

JAVA实现

一、静态代理
1、静态代理:代理和被代理对象在【代理之前】都是【确定】的。他们都实现【相同的接口或者继承相同的抽象类】
2、代理实现方法:
(1)继承法:代理类直接【继承】被代理类,实现其原有方法,并添加一些额外功能
(2)聚合方法:代理类实现【相同的功能接口:很重要,事项相同接口,不同代理也可以进行相互代理】,并在内声明一个被代理类的对象

下面重点说说动态代理:
二、动态代理
1、 JDK动态代理:
- 创建一个实现接口invocationhandler的类,它必须实现invoke方法
- 创建被代理的类以及接口
- 调用Proxy的静态方法,创建一个代理类: newProxyInstance
- 通过代理调用目标方法

例如:
抽象角色:

 public interface Subject  { 
    abstract public void request(); 
}  

具体角色RealSubject:

 public  class  RealSubject  implements  Subject {

   public  RealSubject() {} 

    public   void  request() {
    System.out.println( " From real subject. " );
  } 

}  

代理类:

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

 public   class  DynamicSubject  implements  InvocationHandler  {
   private  Object sub;
   public  DynamicSubject()  {} 


    public  DynamicSubject(Object obj)  {
    sub  =  obj;
  } 

 public  Object invoke(Object proxy, Method method, Object[] args)  throws  Throwable  {
    //第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。
   System.out.println( " before calling  "   +  method);
   method.invoke(sub,args);

   System.out.println( " after calling  "   +  method);
    return   null ;
 } 

} 

测试执行客户端:

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

 public   class  Client  { 

 static   public   void  main(String[] args)  throws  Throwable  { 

   RealSubject rs  =   new  RealSubject();  // 在这里指定被代理类  
    InvocationHandler ds  =   new  DynamicSubject(rs); 
   Class<?> cls  =  rs.getClass(); 

    // 以下是一次性生成代理 
    Subject subject  =  (Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(),ds ); 
   subject.request(); 

}  

运行结果:

2.CGLIB动态代理:

3、 自定义动态代理:
- 声明一段源码(动态产生代理)
- 编译源码(JDK Compiler API),产生新的类(代理类)
- 将这个类load到内存当中,产生一个新的对象(代理对象)
- return代理对象

python实现

在代理类中覆盖真实对象的方法,并在执行真实对象的方法之前(后),增加代理自己的逻辑。这里有些类似于JAVA中的静态代理。

class Interface :
    def Request(self):
        pass

class RealSubject(Interface): 
    def Request(self):
        print "Real request."

class Proxy(Interface):
    def Request(self):
        print "before request"
        self.real = RealSubject()
        self.real.Request()
        print "after request"


if __name__ == "__main__":
    p = Proxy()
    p.Request()

运行的结果:

那么python能像java那样实现动态代理吗,我这边暂时没有想到什么好的方案,但是我们可以将代理类写的更加抽象一些:

class RealSubject():
    def Request1(self):
        print "Real request1."
    def Request2(self):
        print "Real request2."

class Proxy(object):
    def __init__(self, subject):
        self.__subject = subject
    def __getattr__(self, name):
        return getattr(self.__subject, name)

class SomeProxy(Proxy):
    def Request2(self):
        pass

if __name__ == "__main__":
    p = SomeProxy(RealSubject())
    p.Request1()
    p.Request2()

这样的运行结果只会输出Real request1,因为request2被代理类重写掉了。

使用代理模式的好处:
1、一个代理类调用原有的方法,且对产生的结果进行控制。
2、可以将功能划分的更加清晰,有助于后期维护。


转载请注明出处:http://www.opscoder.info/proxy.html

其他分类: