回答:
ファサードパターンのwikiページには、この程度の簡単なノートを持っています。
「アダプターは、ラッパーが特定のインターフェースを尊重し、ポリモーフィックな動作をサポートする必要がある場合に使用されます。一方、ファサードは、より簡単または単純なインターフェースを操作したい場合に使用されます。」
さまざまなステレオシステムすべてで動作するように設定したユニバーサルリモコンを考える必要があるというアナロジーを聞きました。「オン」を押すと、ケーブルボックス、レシーバー、テレビの電源が入ります。多分それは本当に豪華なホームシアターであり、それはライトを暗くし、色合いも描画します。それはファサードです-より複雑な一連のステップを処理する1つのボタン/機能。
Adapterパターンは、2つの互換性のないインターフェースをリンクするだけです。
編集:(コメントに基づく)アダプターパターンの簡単な例えは、DVI-to-VGAアダプターのようなものです。最近のビデオカードは多くの場合DVIですが、古いVGAモニターを使用しています。ビデオカードの予想されるDVI入力にプラグインし、独自のVGA入力を備えたアダプターを使用すると、古いモニターを新しいビデオカードで動作させることができます。
InputStreamReader
適合させるInputStream
にReader
してOutputStreamWriter
いる適合させOutputStream
にWriter
異なる抽象型である両方。
正直なところ、多くのパターンをプログラムで同じ方法で実装できます。違いは意図的なものです。
アダプター設計パターンは、1つ以上のクラスのインターフェースを、クライアントが使用することを期待するインターフェースに「変換」することを意図しています。アダプターは、期待されるインターフェースへの呼び出しを、ラップされたクラスが使用する実際のインターフェースに変換します。
Facadeパターンは、よりシンプルなインターフェースが必要な場合に使用されます(また、問題のクラスをラップすることで同じ方法で実装できます)。必要な場合にのみ、既存のインターフェースに互換性がない場合でも、ファサードを使用しているとは言えません。読みやすくしたり、デザインが悪くないようにするためなど。
ファサード:
要点:(Pankaj Kumarによるjournaldev記事より)
ファサードクラス図:
アダプタ:
アダプターのクラス図:
アダプターの詳細については、このSEの投稿をご覧ください。
主な違い:
someMethod(int year, int month)
に委任された、someMethod(DateTime start, DateTime end)
または委任されたと言いましょsomeMethod()
うsomeMethod(T param)
の目的
ファサードはシンプルです
アダプターは相互運用性です。
ファサードは通常、アダプターと対照的です。
+--------------------------------------------------------------+-----------------------------------------------+
| Facade | Adapter |
+--------------------------------------------------------------+-----------------------------------------------+
| Simplifies multiple complex components with single interface | Provides differnet interface for an interface |
| Works with multiple components | Works with single component |
| Control panel is an example | A power adapter is an example |
| High-level interface | Low-level interface |
+--------------------------------------------------------------+-----------------------------------------------+
これについては、あまり形式的なことなく、わかりやすい言葉で説明しようと思います。
いくつかのドメインクラスがあり、UIからそれらとやり取りしたいとします。ファサードは、UIレイヤーがファサード以外のドメインクラスを認識しないように、UIレイヤーから呼び出すことができる関数を提供するために使用できます。つまり、ドメインクラスの関数を呼び出す代わりに、ファサードから単一の関数を呼び出します。ファサードは、他のクラスから必要な関数を呼び出す責任があります。
一方、アダプターは、必要な機能と同じ機能を持つ他の外部コンポーネントを統合するために使用できますが、それらの機能はまったく同じ方法で呼び出されません。あなたが持っていると言うCar
ドメイン内のクラスを、あなたがうまくとして定義Carクラスを持つ外部の車のプロバイダで動作します。このクラスには関数car.getDoors()
がありますが、外部プロバイダーにも同等の機能がありますcar.getNumDoors()
。この関数の呼び出し方法を変更したくないので、アダプタークラスを使用して外部CarクラスをラップしgetDoors()
、アダプターの呼び出しをgetNumDoors()
外部クラスに委任できます。
アダプター・パターンは、新しいインターフェースを提供することにより、互換性のない2つのインターフェースをリンクします。
ファサードパターンは、単一のインターフェースで(複数のコンポーネントを持つ)複雑なサブシステムを簡素化します。
これら2つのパターンの違いは明らかですが、デザインパターンの領域ではなく、ドメインモデリングです。以下にその理由を説明します。
最初に、他の人がここで言ったことを繰り返し説明し、次にメモを追加します。
Facadeは、サブシステム(外部システムまたはレガシーシステム)へのインターフェースであり、クライアント(米国)のアクセスを簡素化します。Facadeは他のサブシステムのインターフェースを非表示にする(一部の呼び出しを集約するか、必要のない一部のAPIを非表示にする)ため、クライアントはこのFacadeを通じてのみそのサブシステムにアクセスします。
一方、アダプタは別のサービスまたはオブジェクトのラッパーです。ラップされたオブジェクトを、クライアントが期待する標準インターフェースに準拠させます。「元帳」オブジェクトに、微調整(パラメーターの変更、名前の変更など)が必要なメソッドがあるとします。アダプターで包むことができます。
しかし、それでも違いは明らかではないかもしれません。ここで、これらの2つのパターンの主な違いを取り上げ、さらに混乱する余地を残します。
Facadeは他のサブシステムのドメインモデルを変更しませんが、Adapterは変更します。 これが大きな違いです。限目。
腐敗防止レイヤーを作成するときにこれらの2つを組み合わせるのはそのためです。使用したいサブシステムがあるが、そのドメインモデルがドメインモデルを混乱させたくないとします。あなたならどうしますか?腐敗防止レイヤーを作成します。どうやって?最初に、サブシステムのインターフェースへのアクセスを簡略化するFacadeを作成し、次にそのインターフェースで使用されるドメインオブジェクトのアダプターを作成します(ファサードは他のサブシステムのドメインモデルを保持していることに注意してください)。
ドメインモデリングでは、多くのデザインパターンを使用できます。これは、ファサードとアダプタのデザインパターンにも当てはまります。これら2つのパターンの違いは「設計パターン」レルムでは明確ではないかもしれませんが、「ドメインモデリング」レルムではより明確です。