プロキシモード


プロキシ パターンでは、1 つのクラスが別のクラスの機能を表します。このタイプのデザインパターンは構造パターンです。

プロキシ パターンでは、外部の世界に機能的なインターフェイスを提供するために、既存のオブジェクトを使用してオブジェクトを作成します。

はじめに

目的: このオブジェクトへのアクセスを制御するために、他のオブジェクトにプロキシを提供します。

主な解決策: オブジェクトに直接アクセスするときに発生する問題。たとえば、アクセスされるオブジェクトがリモート マシン上にある場合。オブジェクト指向システムでは、一部のオブジェクトに直接アクセスすると、特定の理由 (たとえば、オブジェクトの作成にコストがかかる、特定の操作にセキュリティ制御が必要である、またはアウトプロセスが必要であるなど) により、ユーザーまたはシステム構造に多大な問題が発生します。このオブジェクトにアクセスするときに、このオブジェクトにアクセス レイヤを追加できます。

いつ使用するか: クラスにアクセスするときに何らかの制御が必要です。

解決方法: 中間レイヤーを追加します。

キーコード: 実装とプロキシクラスの組み合わせ。

アプリケーションの例: 1. Windows のショートカット。 2. Zhu Bajie が Gao Cuilan を探しに行ったとき、彼は Sun Wukong であることが判明しました。これは次のように理解できます。Gao Cuilan の外観は抽象化されており、Zhu Bajie が Gao Cuilan を訪れたとき、Gao Cuilan と Sun Wukong の両方がこのインターフェイスを実装しました。彼はこれが孫悟空であるとは分からなかったので、孫悟空はガオ・翠蘭のエージェントクラスであると言われました。 3. 駅で切符を購入する必要はありません。代理店に行くこともできます。 4. 小切手または銀行預金証明書は、口座内の資金の代理となります。小切手は市場取引で現金の代わりに使用され、発行者の口座に保持されている資金を管理します。 5.スプリングオープ。

利点: 1.責任が明確です。 2. 高い拡張性。 3. インテリジェント。

短所: 1. クライアントと実際のトピックの間にプロキシ オブジェクトが追加されるため、一部の種類のプロキシ モードではリクエストの処理速度が遅くなる可能性があります。 2. プロキシ モードの実装には追加作業が必要で、一部のプロキシ モードの実装は非常に複雑です。

使用シナリオ: 責任ごとに分けると、通常は次の使用シナリオがあります。 1. リモートエージェント。 2. 仮想エージェント。 3. コピーオンライトエージェント。 4. 保護 (保護またはアクセス) エージェント。 5. キャッシュエージェント。 6. ファイアウォールプロキシ。 7. 同期エージェント。 8. スマートリファレンスエージェント。

注: 1. アダプター パターンとアダプター パターンの違い: アダプター パターンは主に検討中のオブジェクトのインターフェイスを変更しますが、プロキシ パターンはプロキシ クラスのインターフェイスを変更できません。 2. デコレータ モードとデコレータ モードの違い: デコレータ モードは機能を拡張するものであり、プロキシ モードは機能を制御するものです。

実装

ImageインターフェースとImageインターフェースを実装するエンティティクラスを作成します。 ProxyImage は、RealImage オブジェクトの読み込みのメモリ フットプリントを削減するプロキシ クラスです。

ProxyPatternDemo のデモ クラスは、ProxyImage を使用して、ロードされる Image オブジェクトを取得し、必要に応じて表示します。

proxy_pattern_uml_diagram.jpg

ステップ 1

インターフェースを作成します。

Image.java

public interface Image {
   void display();
}

ステップ 2

インターフェースを実装するエンティティクラスを作成します。

RealImage.java

public class RealImage implements Image {

   private String fileName;

   public RealImage(String fileName){
      this.fileName = fileName;
      loadFromDisk(fileName);
   }

   @Override
   public void display() {
      System.out.println("Displaying " + fileName);
   }

   private void loadFromDisk(String fileName){
      System.out.println("Loading " + fileName);
   }
}

ProxyImage.java

public class ProxyImage implements Image{

   private RealImage realImage;
   private String fileName;

   public ProxyImage(String fileName){
      this.fileName = fileName;
   }

   @Override
   public void display() {
      if(realImage == null){
         realImage = new RealImage(fileName);
      }
      realImage.display();
   }
}

ステップ 3

要求されたら、ProxyImageを使用してクラスRealImageのオブジェクトを取得します。

ProxyPatternDemo.java

public class ProxyPatternDemo {
	
   public static void main(String[] args) {
      Image image = new ProxyImage("test_10mb.jpg");

      //图像将从磁盘加载
      image.display(); 
      System.out.println("");
      //图像将无法从磁盘加载
      image.display(); 	
   }
}

ステップ 4

出力を確認します。

りー