Java設計モード(10)エージェントモード(Proxyモード)


設計モデルを理解して使用することで、オブジェクト向けのプログラミング習慣を育成することができ、同時に実際の応用では、魚が水を得て、余裕を楽しむことができます.Proxyは比较的に役に立つ1种のモードで、その上変种が多くて、応用の场合は小さい构造から全体のシステムの大きい构造までカバーして、Proxyは代理の意味で、私达は代理サーバーなどの概念があるかもしれなくて、代理の概念は解釈することができます:出発点から目的地の间に1つの中间层があって、代理を意味します.設計モードで定義:このオブジェクトへのアクセスを制御するために他のオブジェクトにエージェントを提供します.
プロキシモードを使用する理由
  • 授権メカニズムの異なるレベルのユーザーは同じオブジェクトに対して異なるアクセス権利を持っており、例えばJiveフォーラムシステムではProxyを使用して授権メカニズムの制御を行い、アクセスフォーラムには登録ユーザーと観光客(未登録ユーザー)の2人があり、JiveではForumProxyのようなエージェントを通じてこの2つのユーザーのフォーラムへのアクセス権限を制御する.
  • クライアントは、オブジェクトに直接操作することはできませんが、そのオブジェクトとインタラクティブになる必要があります.

  • 2つの具体的な例を示します.
  • そのオブジェクトが大きなピクチャである場合、表示に時間がかかるため、このピクチャがドキュメントに含まれている場合は、エディタまたはブラウザを使用してこのドキュメントを開く必要があります.ドキュメントを開くには、高速でなければなりません.大きなピクチャの処理が完了するのを待つことはできません.この場合、本当のピクチャの代わりにピクチャProxyを作成する必要があります.
  • そのオブジェクトがインターネットのあるリモートサーバ上で、このオブジェクトを直接操作するのは、ネットワーク速度のために遅い可能性がある場合は、まずProxyでそのオブジェクトの代わりに使用することができます.

  • 要するに、コストがかかるオブジェクトは、使用時にのみ作成され、貴重なJavaメモリを多く節約できます.だから、Javaはリソースメモリを消費すると思っている人もいますが、これはプログラム作成の考え方とも関係があると思います.
    プロキシ・モードの使用方法
    Jiveフォーラムシステムを例にとると、フォーラムシステムにアクセスするユーザーには、一般ユーザー、フォーラム管理者、システム管理者、観光客を登録するさまざまなタイプがあります.一般ユーザーを登録してから発言することができ、フォーラム管理者は彼が授権されたフォーラムを管理することができ、システム管理者はすべての事務を管理することができ、これらの権限の区分と管理はProxyを使用して完成した.ForumはJiveのコアインタフェースで、フォーラム名、フォーラム記述の取得と修正、投稿発表削除編集など、フォーラム操作に関する主な行為がForumに陳列されています.ForumPermissionsでは、さまざまなレベルの権限を持つユーザーを定義します.
    public class ForumPermissions implements Cacheable {
    
    /**
    
    * Permission to read object.
    
    */
    
    public static final int READ = 0;
    
    
    
    /**
    
    * Permission to administer the entire sytem.
    
    */
    
    public static final int SYSTEM_ADMIN = 1;
    
    
    
    /**
    
    * Permission to administer a particular forum.
    
    */
    
    public static final int FORUM_ADMIN = 2;
    
    
    
    /**
    
    * Permission to administer a particular user.
    
    */
    
    public static final int USER_ADMIN = 3;
    
    
    
    /**
    
    * Permission to administer a particular group.
    
    */
    
    public static final int GROUP_ADMIN = 4;
    
    
    
    /**
    
    * Permission to moderate threads.
    
    */
    
    public static final int MODERATE_THREADS = 5;
    
    
    
    /**
    
    * Permission to create a new thread.
    
    */
    
    public static final int CREATE_THREAD = 6;
    
    
    
    /**
    
    * Permission to create a new message.
    
    */
    
    public static final int CREATE_MESSAGE = 7;
    
    
    
    /**
    
    * Permission to moderate messages.
    
    */
    
    public static final int MODERATE_MESSAGES = 8;
    
    
    
    .....
    
    
    
    public boolean isSystemOrForumAdmin() {
    
     return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]);
    
    }
    
    
    
    .....
    
    
    
    }

    したがって,Forumにおける様々な操作権限はForumPermissionsが定義したユーザレベルと関係があり,インタフェースForumの実現としてForumProxyはこの対応関係を結びつける.たとえば、Forumの名前を変更すると、フォーラム管理者またはシステム管理者のみが変更できます.コードは次のとおりです.
    public class ForumProxy implements Forum {
    
        private ForumPermissions permissions;
    
        private Forum forum;
    
        this.authorization = authorization;
    
    
    
        public ForumProxy(Forum forum, Authorization authorization,
    
        ForumPermissions permissions){
    
            this.forum = forum;
    
            this.authorization = authorization;
    
            this.permissions = permissions;
    
        }
    
        .....
    
        public void setName(String name) throws UnauthorizedException,
    
            ForumAlreadyExistsException{
    
      //                  
    
      if (permissions.isSystemOrForumAdmin()) {
    
       forum.setName(name);
    
      }
    
      else {
    
       throw new UnauthorizedException();
    
      }
    
        }
    
        ...
    
    
    
    }

     
    DbForumこそインタフェースForumの真の実現であり、フォーラム名の変更を例に挙げます.
    public class DbForum implements Forum, Cacheable {
    
        ...
    
        public void setName(String name) throws ForumAlreadyExistsException {
    
      ....
    
      this.name = name;
    
      //               
    
      saveToDb();
    
      ....
    
        }
    
        ...
    
    }

    フォーラム名の変更に関連する場合、他のプログラムはまずForumProxyと付き合わなければなりません.ForumProxyが同じことをする権限があるかどうかを決定します.ForumProxyは名実ともに「ゲートウェイ」であり、「セキュリティエージェントシステム」です.普段のアプリケーションでは、Proxyを意識的に使用しているかどうかにかかわらず、システムのライセンスやセキュリティシステムに関わることは避けられません.実際にはProxyを使用しています.私たちはJiveと結びつけて深く話し続けます.次は工場モデルについて話します.Forumを使用するにはForumProxyを使用する必要があり、JiveでForumを作成するにはFactoryモードを使用し、全体的な抽象クラスForumFactoryがあり、この抽象クラスではForumFactoryを呼び出すのはgetInstance()メソッドで実現され、ここではSingleton(設計モードの1つでもある)を使用し、getInstance()はForumFactoryProxyを返します.ForumFactoryを返さずにForumFactoryの実装ForumFactoryProxyを返すのはなぜですか?理由は明らかで、forumを作成する権限があるかどうかをエージェントで決定する必要があります.ForumFactoryProxyでは、次のコードが表示されます.
    public class ForumFactoryProxy extends ForumFactory {
    
     protected ForumFactory factory;
    
     protected Authorization authorization;
    
     protected ForumPermissions permissions;
    
    
    
     public ForumFactoryProxy(Authorization authorization, ForumFactory factory,ForumPermissions permissions){
    
      this.factory = factory;
    
      this.authorization = authorization;
    
      this.permissions = permissions;
    
     }
    
    
    
     public Forum createForum(String name, String description)
    
      throws UnauthorizedException, ForumAlreadyExistsException{
    
      //            forum
    
      if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) {
    
       Forum newForum = factory.createForum(name, description);
    
       return new ForumProxy(newForum, authorization, permissions);
    
      }
    
      else {
    
       throw new UnauthorizedException();
    
      }
    
        }
    
    }

    メソッドcreateForumが返すのもForumProxyで、Proxyは壁のようで、他のプログラムはProxyとインタラクティブに操作するしかありません.ここには2つのProxyがあります.ForumProxyとForumFactoryProxyです.2つの異なる役割を表します.Forumの使用とForumの作成です.使用オブジェクトと作成オブジェクトを分離する理由についても、Factoryモードを使用する理由は、「カプセル化」「割り当て」のためです.言い換えれば、できるだけ機能を単一化し、メンテナンス・修正を容易にする.Jiveフォーラムシステムでは、投稿の作成や使用など、Forumという考え方に従っています.以上、Proxyを使用して認証メカニズムにアクセスする方法について議論したが、Proxyはユーザーにcopy-on-writeと呼ばれる別の最適化方法を隠すこともできる.膨大で複雑なオブジェクトをコピーするのはオーバーヘッドが大きい操作であり、コピー中に元のオブジェクトに変更がなければ、このようなコピーオーバーヘッドは必要ありません.このコピープロセスをエージェントで遅延します.たとえば、hashtableなどの大きなCollectionがあり、多くのクライアントが同時にアクセスします.特定のクライアントの1つが連続したデータ取得を行う場合、他のクライアントがhashtableに追加または削除できないことが要求されます.最も直接的な解決策は、collectionのlockを使用して、この特別なクライアントにこのlockを取得させ、連続的なデータ取得を行い、lockを解放することです.
    public void foFetches(Hashtable ht){
    
     synchronized(ht){
    
      //           ..
    
     }
    
    }

    しかし、この方法はCollectionをロックするのに時間がかかる可能性があります.この間、他のクライアントはCollectionにアクセスできません.2つ目の解決策は、cloneというCollectionであり、cloneに対して出てきたCollection操作を連続的なデータで取得することです.このスキームの前提は,このCollectionがclone可能であり,深さcloneを提供する方法が必要であることである.Hashtableは自分のcloneメソッドを提供していますが、Keyとvalueオブジェクトのcloneではありません.
    public void foFetches(Hashtable ht){
    
     Hashttable newht=(Hashtable)ht.clone();
    
    }

    問題はまた来て、cloneに対して出てきたオブジェクト操作なので、元の母体が他のクライアント操作によって修正された場合、cloneが出てきたオブジェクト操作には意味がありません.最後の解決策:他のクライアントの修正が完了してからcloneを行うことができます.つまり、この特別なクライアントはまずcloneという方法を呼び出して一連のデータ取得操作を行うことができます.しかし、実際には、他のクライアントがこのオブジェクトCollectionを変更するまで、オブジェクトのコピーは行われません.Proxyを使用してこのスキームを実装します.これがcopy-on-write操作です.Proxyの応用範囲は広く,現在流行している分布計算方式RMIやCorbaなどはProxyモードの応用である.
    シリーズ記事:
    Java設計モード(1)ファクトリモード(Factoryモード)
    Java設計モード(2)ワンストップモード(Singletonモード)
    Java設計モード(3)ビルダーモード(Builderモード)
    Java設計モード(4)プロトタイプモード(Prototypeモード)
    Java設計モード(5)共有モード/享元モード(Flyweightモード)
    Java設計モード(6)ブリッジモード(Bridgeモード)
    Javaデザインモード(7)デコレーションモード(Decoratorモード)
    Java設計モード(8)コンビネーションモード(Compositeモード)
    Java設計モード(9)アダプタモード(Adapterモード)
    Java設計モード(10)エージェントモード(Proxyモード)
    Javaデザインモード(11)外観モード(Facadeモード)
    Java設計モード(12)反復モード(Iteratorモード)
    Java設計モード(13)テンプレートモード(Templateモード)
    Java設計モード(14)責任チェーンモード(Chain of Responsibilityモード)
    Javaデザインモード(15)メモモード(Mementoモード)
    Java設計モード(16)仲介モード(Mediatorモード)
    Java設計モード(17)インタプリタモード(Interpreterモード)
    Java設計モード(18)ポリシーモード(Strategyモード)
    Java設計モード(19)状態モード(Stateモード)
    Java設計モード(20)オブザーバーモード(Observerモード)
    Java設計モード(21)アクセスモード(Visitor者モード)
    Java設計モード(22)コマンドモード(Commandモード)