今日は代理デザインパターンについて見ていきましょう。名前の通り、代理とは仲介者を通じて誰かが何かをすることを代替することです。私たちのプログラムにおいては、代理オブジェクトを通じて特定のオブジェクトの特定のメソッドへのアクセスを制御することに対応します。このメソッドの前後で追加の処理を行うことができます。
- 概念理解
- 静的代理
- 動的代理
概念理解#
- 抽象役割:実際の役割と代理役割が共通して持つメソッドを定義するために使用されます。
- 実際の役割:実際の役割が実装する具体的なビジネスロジックで、代理役割が呼び出します。
- 代理役割:実際の役割を代理し、実際の役割の具体的なロジックの前後で追加の処理を行うことができます。
したがって、代理の意義は、具体的なビジネスロジックが必要なときにのみ実際の役割の具体的なビジネスメソッドを呼び出すことです。つまり、実際の役割の具体的なビジネスロジックに関係のない処理はすべて代理クラス内で行います。
静的代理#
まず、静的代理のコード実装を見てみましょう。抽象役割を定義し、共通のビジネスロジックを宣言します。具体的には以下の通りです:
/**
* 抽象役割
* @author jzman
*/
public interface IBusiness {
/**
* 购物
*/
void buy();
}
次に、実際の役割を作成し、具体的なビジネスロジックを完成させます。具体的には以下の通りです:
/**
* 真实角色
* @author jzman
*/
public class RealRole implements IBusiness{
@Override
public void buy() {
System.out.println("私は物を買いたい");
}
}
次に、代理役割を作成し、具体的なビジネスロジックを実行する際には必ず実際の役割のビジネスロジックメソッドを呼び出す必要があります。具体的には以下の通りです:
/**
* 代理角色
* @author jzman
*/
public class ProxyRole implements IBusiness{
private IBusiness mRealRole;
public ProxyRole(IBusiness realRole) {
this.mRealRole = realRole;
}
@Override
public void buy() {
//購入前の追加評価
System.out.println("購入前の追加評価...");
//具体的なビジネスロジック
mRealRole.buy();
//購入後の満足度調査
System.out.println("購入後の満足度調査...");
}
}
最後に、先ほど作成した関連する静的代理クラスを使用します。具体的には以下の通りです:
/**
* 测试静态代理
* @author jzman
*/
public class StaticClient {
public static void main(String[] args) {
//実際の役割を作成
IBusiness realRole = new RealRole();
//代理役割を作成
IBusiness proxyRole = new ProxyRole(realRole);
//代理購入が物を買う手伝いをする
proxyRole.buy();
}
}
テスト結果は以下の通りです:
購入前の追加評価...
私は物を買いたい
購入後の満足度調査...
このケースでは、代理購入は私たちが物を買う手伝いをするだけでなく、購入行為の前後に追加の処理を行っています。非常に柔軟ではありませんか?
動的代理#
上記で静的代理について理解したので、動的代理と静的代理の違いは何でしょうか。実際、静的代理と動的代理の主な違いは、静的代理は自分で代理クラスを生成する必要があるのに対し、動的代理はコードの実行中に自動的に代理クラスを生成することです。では、動的代理はどのように実装されるのでしょうか。まず、Java JDK に付属する動的代理を実現するための重要な 2 つのクラスまたはインターフェースを見てみましょう。具体的には以下の通りです:
//動的に代理クラスとそのオブジェクトを生成するために使用
java.lang.reflect.Proxy
//代理役割の呼び出し処理プログラムが実装する必要があるインターフェース
//呼び出し元の実装を制約するために使用され、抽象役割の呼び出しメソッドがこのインターフェースのinvokeメソッドによって呼び出されます
java.lang.reflect.InvocationHandler
次に、Java JDK に付属する動的代理を実装します。まず、抽象役割と実際の役割は上記の静的代理と同じですので、ここでは繰り返しません。代理役割の呼び出し処理プログラムを以下のように作成します:
/**
* 代理角色的调用处理程序
* @author jzman
*/
public class BusinessHandler implements InvocationHandler{
private IBusiness mRealRole;
public BusinessHandler(IBusiness mRealRole) {
super();
this.mRealRole = mRealRole;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//購入前の追加評価
System.out.println("購入前の追加評価...");
//実際の役割の具体的なビジネスロジック
method.invoke(mRealRole, args);
//購入後の満足度調査
System.out.println("購入後の満足度調査...");
return null;
}
}
Proxy の静的メソッド newProxyInstance () を使用して代理オブジェクトを生成します。具体的には以下の通りです:
/**
* 测试JDK自带的动态代理
* @author jzman
*
*/
public class DynamicProxyClient {
public static void main(String[] args) {
//実際の役割を作成
IBusiness mRealRole = new RealRole();
//処理プログラムインターフェースを作成
InvocationHandler handler = new BusinessHandler(mRealRole);
/**
* 代理役割に対応する代理オブジェクトを取得
* newProxyInstanceのパラメータ(クラスローダー、自動生成された代理クラスが実装するインターフェース、代理オブジェクトの呼び出し処理プログラム)
*/
IBusiness proxy = (IBusiness) Proxy.newProxyInstance(handler.getClass().getClassLoader(), mRealRole.getClass().getInterfaces(), handler);
//代理役割が物を買う手伝いをする
proxy.buy();
}
}
上記のコードの実行結果は以下の通りです:
購入前の追加評価...
私は物を買いたい
購入後の満足度調査...
静的代理を学ぶことは動的代理の学習に役立ちます。両者の主な違いは、動的代理は代理クラスを書く必要がなく、対応する代理クラスがコードの実行中に動的に生成されることです。もちろん、生成された代理クラスも抽象役割に対応するインターフェースを実装しており、代理役割の呼び出し者処理プログラム(InvocationHandler)も具体的なビジネスロジックを引き継ぎます。静的代理と動的代理についてはここまでです。