web-dev-qa-db-ja.com

ファサード対メディエーター

私はこれら2つのパターンの違いを調査しています。

ファサードはサブシステムへのアクセスをカプセル化し、メディエーターはコンポーネント間の相互作用をカプセル化することを理解しています。

サブシステムコンポーネントはファサードを認識していないことを理解しています。コンポーネントは明らかにメディエーターを認識しています。

現在、構成情報を取得する方法をカプセル化するためにファサードを使用しています。 App.Config、SQLに格納されているユーザー設定、アセンブリ情報など、さまざまなウィンドウフォーム間のナビゲーション用のメディエーター。

ただし、ほとんどのサイトは、メディエーターが「機能を追加する」と指摘しています。これはどういう意味ですか?メディエーターはどのように機能を追加しますか?

75
Tired

...ほとんどのサイトは、メディエーターが「機能を追加する」と指摘しています...

facadeは、異なる観点から既存の機能を公開するだけです。

mediatorは、既存のさまざまな機能を組み合わせて新しい機能を作成するため、機能を「追加」します。

次の例を見てください。

ロギングシステムがあります。そのロギングシステムから、ファイル、ソケット、またはデータベースにログを記録できます。

ファサードデザインパターンを使用すると、既存の機能からのすべての関係を、ファサードが公開する1つの「インターフェース」の背後に「隠す」ことができます。

クライアントコード:

 Logger logger = new Logger();
 logger.initLogger("someLogger");
 logger.debug("message");

実装には、多くのオブジェクトの相互作用が含まれる場合があります。しかし、最終的には、機能はすでに存在しています。おそらく、「デバッグ」メソッドは次のように実装されています。

実装:

 class Logger { 

      private LoggerImpl internalLogger;
      private LoggerManager manager;

      public void initLogger( String loggerName ) {
          this.internalLogger = manager.getLogger( loggerName ); 
      }

      public void debug( String message ) { 
          this.internalLogger.debug( message );
      }     
 }

機能はすでに存在しています。ファサードはそれを隠すだけです。この架空のケースでは、LoggerManagerが正しいロガーの作成を処理し、LoggerImplは「デバッグ」メソッドを持つパッケージプライベートオブジェクトです。このように、Facadeは機能を追加せず、いくつかの既存のオブジェクトに委任するだけです。

一方、メディエーターは、さまざまなオブジェクトを組み合わせて新しい機能を追加します。

同じクライアントコード:

 Logger logger = new Logger();
 logger.initLogger("someLogger");
 logger.debug("message");

実装:

 class Logger { 

      private Java.io.PrintStream out;
      private Java.net.Socket client;
      private Java.sql.Connection dbConnection;
      private String loggerName;


      public void initLogger( String loggerName ) {
               this.loggerName = loggerName;
               if ( loggerName == "someLogger" ) { 
                    out = new PrintStream( new File("app.log"));
               } else if ( loggerName == "serverLog" ) { 
                    client = new Socket("127.0.0.1", 1234 );
               } else if( loggerName == "dblog") { 
                    dbConnection = Class.forName()... .
               }

      }

      public void debug( String message ) { 

               if ( loggerName == "someLogger" ) { 
                    out.println( message );
               } else if ( loggerName == "serverLog" ) { 
                    ObjectOutputStrewam oos = 
                           new ObjectOutputStrewam( client.getOutputStream());
                    oos.writeObject( message );
               } else if( loggerName == "dblog") { 
                    Pstmt pstmt = dbConnection.prepareStatment( LOG_SQL );
                    pstmt.setParameter(1, message );
                    pstmt.executeUpdate();
                    dbConnection.commit();
               }
      }
 }

このコードでは、メディエーターは、適切な「チャネル」を作成してログに記録し、そのチャネルにログを記録するビジネスロジックを含むメディエーターです。メディエーターは機能を「作成」しています。

もちろん、ポリモーフィズムを使用してこれを実装するより良い方法がありますが、ここでのポイントは、メディエーターが既存の機能を組み合わせることによって新しい機能を「追加」する方法を示すことです(私のサンプルでは申し訳ありませんでした)メディエーターを想像して、読んでくださいデータベースから、ログを記録するリモートホスト、次にクライアントを作成し、最後にそのクライアントの印刷ストリームにログメッセージを書き込みます。このようにして、メディエーターは異なるオブジェクト間を「仲介」します。

最後に、facadeは構造パターンです。つまり、オブジェクトの構成を記述しますが、mediatorは動作です。つまり、オブジェクトが相互作用する方法を記述します。

これがお役に立てば幸いです。

94
OscarRyz

メディエーターを使用してログファイル機能を追加しています。

それはこのように動作します:

  • Obj Aは、調停者に何かする必要があることを伝えます。
  • メディエーターは、さまざまなクライアントオブジェクトにメッセージを送信します。
  • Obj BはObj Aが必要とすることを行い、適切なメッセージをメディエーター経由で送り返します。
  • 一方、Obj Cもメディエーターによって両方のメッセージが送信され、結果をログに記録します。これにより、ログファイルからユーザーの統計情報を取得できます。
  • Obj Dもエラーチェッカーである可能性があるため、Obj BがObj Aのリクエストが不可能であると応答した場合、Obj Dがユーザーにそのことを報告する可能性があります。エラーは通常のアクティビティとは異なるファイルに記録できるようになり、他の手段を使用して、Obj Aが実際に気にする必要のない動作(ビープ音など)を実行できるようになりました。
12
mmr

関連するパターンの下で、 gof は次のように述べています。そのプロトコルは単方向です。つまり、Facadeオブジェクトはサブシステムクラスの要求を行いますが、その逆は行いません。対照的に、メディエーターは、同僚のオブジェクトが提供できない、または提供できない協調動作を可能にし、プロトコルは多方向です。

10
Ray Tayek

簡単な例を挙げましょう。

ファサード:呼び出し時の駐車場のような

parkingLot.Out(car1);

mabは単純なチェーンで動作します:

{
  car1.StartEngin();      
  attendant.charge();
  car1.driverOut();
}

メディエーター:信号機のように。

光と車の間には相互作用があり、

車はその状態によって制御されます。

多分これはメディエーターが「機能を追加する」


そして定義について:

ファサードのタイプ:構造

調停者のタイプ:行動

componentsについてより懸念されるファサードはcontainednified interfaceで、

メディエーターの懸念howオブジェクトのセットinteract

6
yoyo

区別は方向性があると思いました。ファサードはクライアントとファサードの間の一方向の通信です。メディエーターは、クライアントとメディエーターの間でメッセージがやり取りされる双方向の会話にすることができます。

4
duffymo

「デザインパターン」の本から、メディエーターパターンのキーは次のように説明されています。

言い換えると、メディエーターオブジェクトは、協調オブジェクトのグループ内の他のすべてのオブジェクトと、それらがどのように相互作用するかを知っている唯一のスーパーオブジェクトです。他のすべてのオブジェクトは、互いにではなく、メディエーターオブジェクトと対話する必要があります。

対照的に、ファサードは、サブシステムのコンポーネント間ではなく、サブシステムのコンシューマーが使用するための、サブシステム内の一連のインターフェースの「統合インターフェース」です。

3
Hwisung Im

このSEの質問でファサードパターンの詳細を確認できます。

ファサードデザインパターンとは

Facadeは、複雑なシステムへのシンプルで統一されたインターフェースを提供します。

実世界の例(cleartrip flight + hotel booking)は、この投稿にあります。

ファサードデザインパターンとは

Mediator パターン:オブジェクトのセットがどのように相互作用するかをカプセル化するオブジェクトを定義します。 Mediatorは、オブジェクトがお互いを明示的に参照しないようにすることで疎結合を促進し、相互作用を個別に変化させることができます。

メッシュネットワークトポロジの実際の例は、以下のSEの質問で提供されています。

メディエーター対オブザーバーオブジェクト指向設計パターン

Mediatorへのクエリに関して責任が追加されます。

  1. Facadeは既存のサブシステムへのインターフェースのみを提供します。既存のサブシステムはFacadeクラス自体を認識していません。

  2. メディエーターは同僚オブジェクトについて知っています。異なる同僚間のコミュニケーションを可能にします。リンクされた質問で引用した例では、ConcreteMediatorNetworkMediator)は、1人の同僚の登録および登録解除イベントの通知をすべてに送信します他の同僚。

1
Ravindra babu

どちらも別のオブジェクトグループに何らかのポリシーを課します。 Facadeは上からポリシーを課し、Mediatorは下からポリシーを課します。 Mediatorの使用は非表示で有効になっていますが、Facadeの使用は表示および制約されています。

Facadeパターンは、複雑で一般的なインターフェースを持つオブジェクトのグループにシンプルで特定のインターフェースを提供する場合に使用されます。

Mediatorパターンもポリシーを課します。ただし、Facadeはポリシーを可視的かつ制約的な方法で課したのに対し、Mediatorはポリシーを隠された制約のない方法で課します。

アジャイルソフトウェア開発、原則、パターン、および実践Robert C. Martin

1
Mohammad Akbari