88

この2パターンの違いを調べてみました。

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

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

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

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

4

8 に答える 8

107

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

ファサードは、既存の機能を別の観点からのみ公開します

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

次の例を見てください。

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

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

クライアントコード:

 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は「debug」メソッドを持つパッケージプライベートオブジェクトです。このように、ファサードは機能を追加せず、既存のオブジェクトに委任するだけです。

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

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

 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();
               }
      }
 }

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

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

最後に、ファサードは構造パターンです。つまり、オブジェクトの構成を記述しますが、メディエーターは動作を記述します。つまり、オブジェクトが相互作用する方法を記述します。

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

于 2009-01-27T04:53:07.703 に答える
13

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

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

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

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

于 2009-01-27T02:07:38.537 に答える
3

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

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

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

于 2011-01-12T04:09:19.077 に答える