Javaの静的エージェントと動的エージェント


1.エージェント・モードには、静的エージェントと動的エージェントの2種類があります.
2.静的エージェント:
例えば「HelloWorld」を出力する前に文字列「Welcome」を印刷する
A:まずインタフェースクラスを定義する
package ttitfly.proxy;       
      
public interface HelloWorld {       
    public void print();       
//  public void say();       
}   

package ttitfly.proxy;    
   
public interface HelloWorld {    
    public void print();    
//  public void say();    
}    

B:インタフェースの実装クラスを定義する
package ttitfly.proxy;       
      
public class HelloWorldImpl implements HelloWorld{       
      
    public void print(){       
        System.out.println("HelloWorld");       
    }       
//  public void say(){       
//      System.out.println("Say Hello!");       
//  }       
}      

package ttitfly.proxy;    
   
public class HelloWorldImpl implements HelloWorld{    
   
    public void print(){    
        System.out.println("HelloWorld");    
    }    
//  public void say(){    
//      System.out.println("Say Hello!");    
//  }    
}    

C:静的エージェントクラスを定義する

package ttitfly.proxy;       
      
public class StaticProxy implements HelloWorld{       
      
    public HelloWorld helloWorld ;       
    public StaticProxy(HelloWorld helloWorld){       
        this.helloWorld = helloWorld;       
    }       
           
    public void print(){       
        System.out.println("Welcome");       
        //            
        helloWorld.print();       
    }       
           
//  public void say(){       
//      //            
//      helloWorld.say();       
//  }       
}      

package ttitfly.proxy;    
   
public class StaticProxy implements HelloWorld{    
   
    public HelloWorld helloWorld ;    
    public StaticProxy(HelloWorld helloWorld){    
        this.helloWorld = helloWorld;    
    }    
        
    public void print(){    
        System.out.println("Welcome");    
        //         
        helloWorld.print();    
    }    
        
//  public void say(){    
//      //         
//      helloWorld.say();    
//  }    
}    

D:テストクラス:
package ttitfly.proxy;       
      
public class TestStaticProxy {       
      
    public static void main(String[] args){       
        HelloWorld helloWorld = new HelloWorldImpl();       
        StaticProxy staticProxy = new StaticProxy(helloWorld);       
        staticProxy.print();       
               
//      staticProxy.say();       
    }       
}      

package ttitfly.proxy;    
   
public class TestStaticProxy {    
   
    public static void main(String[] args){    
        HelloWorld helloWorld = new HelloWorldImpl();    
        StaticProxy staticProxy = new StaticProxy(helloWorld);    
        staticProxy.print();    
            
//      staticProxy.say();    
    }    
}    

静的エージェントクラスには不快な欠点があることがわかります.インタフェースにメソッドを追加すると(上のすべてのコードの注釈を削除)、すべての実装クラスとエージェントクラスで実装する必要があります.これにより、コードの複雑さが増加します.ダイナミックエージェントはこの欠点を回避できます.
3 .ダイナミックエージェント
動的エージェントは、通常のエージェントと比較して、インタフェースで宣言されたすべてのメソッドが1つのセットのメソッドに移行することが最大の利点です.これにより、インタフェースメソッドの数が多い場合、静的エージェントのように各メソッドを中継する必要がなく、柔軟な処理を行うことができます.
動的エージェントクラスはエージェントインタフェースのみであり,エージェントクラスはInvocationHandlerクラスを実現し,invokeメソッドを実現する必要がある.このinvokeメソッドは、プロキシインタフェースのすべてのメソッドを呼び出すときに呼び出される必要があります.このinvokeメソッドが返す値は、プロキシインタフェースの実装クラスです.
エージェントクラス:
package ttitfly.proxy;           
          
import java.lang.reflect.InvocationHandler;           
import java.lang.reflect.Method;           
import java.lang.reflect.Proxy;           
//           ,        InvocationHandler ,  invoke  。 invoke                      , invoke                             
public class DynamicProxy implements InvocationHandler{           
               
    private Object object;            
    //    ,          (         )          ,  invoke  。       
    //Proxy.newProxyInstance                          InvocationHandler invoke         
    public Object bindRelation(Object object){            
        this.object = object;           
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);            
    }            
    //                                
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {            
        System.out.println("Welcome");           
        Object result = method.invoke(object, args);            
        return result;           
    }           
          
}          

package ttitfly.proxy;        
       
import java.lang.reflect.InvocationHandler;        
import java.lang.reflect.Method;        
import java.lang.reflect.Proxy;        
//           ,        InvocationHandler  ,  invoke  。 invoke                      , invoke                          
public class DynamicProxy implements InvocationHandler{        
            
    private Object object;         
    //    ,          (         )          ,  invoke  。    
    //Proxy.newProxyInstance                          InvocationHandler invoke      
    public Object bindRelation(Object object){         
        this.object = object;        
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);         
    }         
    //                             
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {         
        System.out.println("Welcome");        
        Object result = method.invoke(object, args);         
        return result;        
    }        
       
}        

テストクラス:
package ttitfly.proxy;           
          
public class TestDynamicProxy {           
    public static void main(String[] args){           
        HelloWorld helloWorld = new HelloWorldImpl();           
        DynamicProxy dp = new DynamicProxy();           
        //       HelloWorld,   HelloWorld      。       ,      HelloWorld          。           
        HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);            
        helloWorld1.print();            
        helloWorld1.say();           
               
        //helloWorld2            
        HelloWorld helloWorld2 = new HelloWorldImpl();       
        helloWorld2.print();            
        helloWorld2.say();       
               
    }           
}          

package ttitfly.proxy;        
       
public class TestDynamicProxy {        
    public static void main(String[] args){        
        HelloWorld helloWorld = new HelloWorldImpl();        
        DynamicProxy dp = new DynamicProxy();        
        //       HelloWorld,   HelloWorld      。       ,      HelloWorld          。        
        HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);         
        helloWorld1.print();         
        helloWorld1.say();        
            
        //helloWorld2         
        HelloWorld helloWorld2 = new HelloWorldImpl();    
        helloWorld2.print();         
        helloWorld2.say();    
            
    }        
}        

エージェントクラスにHelloWorldのすべてのメソッドがエージェントされているため、テストクラスで実装クラスのprintメソッドとsayメソッドが呼び出されます.静的エージェントクラスのように一つ一つ実現する必要はありません.
まとめ:プログラマによって作成または特定のツールによって自動的にソースコードを生成し、コンパイルします.プログラムが実行される前に、エージェントクラスの.classファイルはすでに存在します.
動的エージェントクラス:プログラム実行時に反射メカニズムを用いて動的に作成されます.
エージェントクラスは依頼クラスのためにメッセージを前処理したり、メッセージを依頼クラスや事後処理メッセージに転送したりすることができます.動的エージェントクラスのバイトコードは、プログラムの実行時にJava反射メカニズムによって動的に生成され、プログラマが手動でソースコードを書く必要はありません.動的エージェントクラスはプログラミング作業を簡素化するだけでなく、Java反射メカニズムが任意のタイプの動的エージェントクラスを生成できるため、ソフトウェアシステムの拡張性を向上させる.