Javaのプロキシパターン
1. 概要
プロキシパターンを使用すると、コンポーネントの根本的な複雑さを隠しながら、別のリソースへのインターフェイスとして機能する仲介者を作成できます。
2. プロキシパターンの例
初期構成が必要な重いJavaオブジェクト(JDBC接続や SessionFactory など)について考えてみます。
このようなオブジェクトはオンデマンドでのみ初期化する必要があります。初期化したら、すべての呼び出しで再利用します。
次に、このオブジェクトの簡単なインターフェイスと構成を作成しましょう。
public interface ExpensiveObject {
void process();
}
そして、大規模な初期構成でのこのインターフェースの実装:
public class ExpensiveObjectImpl implements ExpensiveObject {
public ExpensiveObjectImpl() {
heavyInitialConfiguration();
}
@Override
public void process() {
LOG.info("processing complete.");
}
private void heavyInitialConfiguration() {
LOG.info("Loading initial configuration...");
}
}
次に、プロキシパターンを利用して、オブジェクトをオンデマンドで初期化します。
public class ExpensiveObjectProxy implements ExpensiveObject {
private static ExpensiveObject object;
@Override
public void process() {
if (object == null) {
object = new ExpensiveObjectImpl();
}
object.process();
}
}
クライアントがprocess()メソッドを呼び出すたびに、クライアントは処理を確認するだけで、初期構成は常に非表示のままになります。
public static void main(String[] args) {
ExpensiveObject object = new ExpensiveObjectProxy();
object.process();
object.process();
}
process()メソッドを2回呼び出していることに注意してください。 舞台裏では、設定部分は、オブジェクトが最初に初期化されるときに1回だけ発生します。
他のすべての後続の呼び出しでは、このパターンは初期構成をスキップし、処理のみが発生します。
Loading initial configuration...
processing complete.
processing complete.
3. プロキシを使用する場合
パターンの使い方を理解することが重要です。
いつを使用するかを理解することが重要です。
プロキシパターンをいつ使用するかについて話しましょう。
- 複雑なオブジェクトや重いオブジェクトの簡略化されたバージョンが必要な場合。この場合、元のオブジェクトをオンデマンドでロードするスケルトンオブジェクトで表すことができます。これは、レイジー初期化とも呼ばれます。 これは仮想プロキシとして知られています
- 元のオブジェクトが異なるアドレス空間に存在し、それをローカルで表現したい場合。 クライアントがローカルアドレス空間に存在するようにアクセスしながら、接続の作成と維持、エンコード、デコードなど、必要なすべての定型的な処理を実行するプロキシを作成できます。 これはリモートプロキシと呼ばれます
- 元の基になるオブジェクトにセキュリティのレイヤーを追加して、クライアントのアクセス権に基づいて制御されたアクセスを提供する場合。 これは保護プロキシと呼ばれます
4. 結論
この記事では、プロキシのデザインパターンについて説明しました。 これは、次の場合に適しています。
- オブジェクトの簡略化されたバージョンが必要な場合、またはオブジェクトにより安全にアクセスしたい場合
- リモートオブジェクトのローカルバージョンが必要な場合
この例の完全なソースコードは、GitHubでから入手できます。