この記事では主にJavaデザインパターンのプロキシモードの注意点を詳しく紹介しますので、興味のある方は参考にしてください
プロキシ(プロキシ)モード:
プロキシモードはオブジェクトベースの構造パターンです。プロキシ パターンはオブジェクトのプロキシ オブジェクトを提供し、プロキシ オブジェクトは元のオブジェクトへの参照を制御します。
コア機能:
プロキシを介してオブジェクトへのアクセスを制御します。
特定(特定の種類)のオブジェクトへのアクセス方法を詳細に制御でき、このメソッドを呼び出す前に前処理を行い、このメソッドを呼び出した後に後処理を行うことができます。つまり、AOP のマイクロ実装です。
AOP (アスペクト指向プログラミング) のコア実装メカニズム。
人生のシナリオ:
いわゆるエージェンシーとは、ある個人または組織が別の個人または組織に代わって行動を起こすことです。場合によっては、クライアントがオブジェクトを直接参照したくない、またはオブジェクトを直接参照できない場合、プロキシ オブジェクトがクライアントとターゲット オブジェクトの間の仲介者として機能することがあります。
例えば、クライアントが歌ってくれるスターを見つけたい場合、まずエージェントを見つける必要があり、その後、エージェントがスターに歌わせるよう手配します。
エージェントは、コンサートの前にいくつかの前処理(面接、契約書作成、署名、前払い金の回収、航空券や車両の手配など)を処理する必要があり、コンサート後のいくつかの後処理(クロージング支払いなど)を処理する必要があります。コンサートが開催されます。この時、あるスター(本物のキャラクター)は歌い方だけを考えればよく、あとはマネージャー(エージェント)に任せられます。
コアの役割:
ここに画像の説明を書きます
抽象オブジェクトの役割: プロキシ オブジェクトと実際のオブジェクトの間の共通インターフェイスを宣言し、プロキシ オブジェクトと実際のオブジェクトのパブリック外部メソッドを定義します。これにより、実際のオブジェクトが使用できる場所であればどこでもプロキシ オブジェクトを使用できるようになります。
実オブジェクトの役割: プロキシ オブジェクトによって表される実オブジェクトを定義します。抽象オブジェクトを実装し、プロキシ オブジェクトによる呼び出しのために実際のオブジェクトによって実装する必要があるビジネス ロジックを定義します。実際のビジネス ロジックに焦点を当てます。
プロキシ オブジェクトの役割: 抽象オブジェクトを実装し、実際のオブジェクトのビジネス ロジック メソッドを通じて抽象メソッドを実装し、独自の操作を付加します。統合されたプロセス制御をプロキシ オブジェクトに組み込みます。
プロキシオブジェクトは内部に実オブジェクトへの参照を含んでおり、実オブジェクトをいつでも操作できるようになっており、プロキシオブジェクトは実オブジェクトと同一のインターフェースを提供し、いつでも実オブジェクトを置き換えることができます。 。プロキシ オブジェクトは通常、単に呼び出しを実際のオブジェクトに渡すのではなく、クライアント呼び出しが実際のオブジェクトに渡される前または後に操作を実行します。
アプリケーションシナリオ:
セキュリティプロキシ: 現実のキャラクターへの直接アクセスをブロックします。
リモート プロキシ: プロキシ クラスを通じてリモート メソッド呼び出しを処理します。
遅延読み込み: 最初に軽量のプロキシ オブジェクトを読み込み、次に必要に応じて実際のオブジェクトを読み込みます。 (画像の遅延読み込み)
カテゴリ:
静的プロキシ: (静的に定義されたプロキシ クラス)
上記の例のコード:
1. プロキシ オブジェクトと実際のオブジェクトの間の共通インターフェイスを宣言します。プロキシ オブジェクトと実際のオブジェクトのパブリック外部メソッド。
public interface Star { /** * 面谈 */ void confer(); /** * 签合同 */ void signContract(); /** * 订票 */ void bookTicket(); /** * 唱歌 */ void sing(); /** * 收钱 */ void collectMoney(); }
2. 実オブジェクトのクラスを定義し、抽象インターフェイスによって提供されるメソッドを実装します。
public class RealStar implements Star { @Override public void bookTicket() { System.out.println("RealStar.bookTicket()"); } @Override public void collectMoney() { System.out.println("RealStar.collectMoney()"); } @Override public void confer() { System.out.println("RealStar.confer()"); } @Override public void signContract() { System.out.println("RealStar.signContract()"); } @Override public void sing() { System.out.println("RealStar.sing()"); } }
3. プロキシ オブジェクトのクラスを定義し、抽象インターフェイスによって提供されるメソッドを実装し、実際のオブジェクトへの参照を保持します。
public class ProxyStar implements Star{ private Star star; public ProxyStar(Star star) { super(); this.star = star; } @Override public void bookTicket() { System.out.println("ProxyStar.bookTicket()"); } @Override public void collectMoney() { System.out.println("ProxyStar.collectMoney()"); } @Override public void confer() { System.out.println("ProxyStar.confer()"); } @Override public void signContract() { System.out.println("ProxyStar.signContract()"); } @Override public void sing() { star.sing(); } }
4. テストクラス
public class Client { public static void main(String[] args) { //定义真实对象角色 Star realStar = new RealStar(); //定义代理对象角色,内部含有真实对象的引用 Star proxyStar = new ProxyStar(realStar); proxyStar.confer(); proxyStar.signContract(); proxyStar.bookTicket(); proxyStar.sing(); proxyStar.collectMoney(); } }
実行結果は次のとおりです:
ProxyStar.confer() ProxyStar.signContract() ProxyStar.bookTicket() RealStar.sing() ProxyStar.collectMoney()
上記の例から、プロキシ オブジェクトがクライアントの呼び出しを実際のオブジェクトに委任していることがわかります。その後、対象オブジェクトのメソッドを呼び出します。その前後で特定の操作を実行できます。
動的プロキシ: (動的に生成されたプロキシクラス):
静的プロキシと比較した動的プロキシの利点:
抽象ロール(インターフェース)で宣言されたすべてのメソッドは、呼び出し側サーバー処理の集中メソッドに転送され、多くのメソッドをより柔軟かつ均一に処理できるようになります。
JDK独自の動的プロキシ
java.lang.reflect.Proxy
プロキシクラスとオブジェクトを動的に生成
java.lang.reflect.InvocationHandler(プロセッサインターフェース)
invokeメソッドを通じて呼び出すことができる現実のキャラクターへのプロキシ アクセスを実現します
Proxy を通じてプロキシ クラス オブジェクトを生成するたびに、対応するプロセッサ オブジェクトを指定する必要があります
テスト コードは次のとおりです:
1. プロキシ オブジェクトと現実のキャラクターの間の共通インターフェイスを宣言します。オブジェクトを作成し、プロキシ オブジェクトと実際のオブジェクトのパブリック外部メソッドを定義します。
public interface Star { /** * 面谈 */ void confer(); /** * 签合同 */ void signContract(); /** * 订票 */ void bookTicket(); /** * 唱歌 */ void sing(); /** * 收钱 */ void collectMoney(); }
2. 実オブジェクトのクラスを定義し、抽象インターフェイスによって提供されるメソッドを実装します。
public class RealStar implements Star { @Override public void bookTicket() { System.out.println("RealStar.bookTicket()"); } @Override public void collectMoney() { System.out.println("RealStar.collectMoney()"); } @Override public void confer() { System.out.println("RealStar.confer()"); } @Override public void signContract() { System.out.println("RealStar.signContract()"); } @Override public void sing() { System.out.println("RealStar.sing()"); } }
3. InvocationHandler プロセッサ インターフェイスを実装する StarHandler クラスを定義すると、invoke メソッドを通じて実際のロールへのプロキシ アクセスを実現でき、invoke メソッドで多くの操作の統合処理を実行することもできます。
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class StarHandler implements InvocationHandler{ private Star realStar; public StarHandler(Star realStar) { super(); this.realStar = realStar; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //返回值 Object object = null; System.out.println("真正的方法执行前!"); System.out.println("面谈,签合同,预付款,订机票"); if(method.getName().equals("sing")){ object = method.invoke(realStar, args); } System.out.println("真正的方法执行后!"); System.out.println("收尾款"); return object; } }
4.客户端测试类
import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { Star realStar = new RealStar(); StarHandler handler = new StarHandler(realStar); //通过Proxy生成代理类对象并指定对应的处理器对象 Star proxyStar = (Star)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler); proxyStar.sing(); }
运行结果如下:
真正的方法执行前!
面谈,签合同,预付款,订机票
RealStar.sing()
真正的方法执行后!
收尾款
开发框架中的应用场景
代理模式在开发框架中的应用场景是非常多的,实际上随便选择一个开发框架都有用到代理模式。例如:
mybatis中实现拦截器插件
AspectJ的实现
spring中AOP的实现
以上がJavaデザインパターンのエージェントパターンに関する注意事項の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。