ウィキペディアの記事を確認したところ、C++ バージョンのコード例が欠落しているようです。これがないと Facade パターンを十分に理解できません。C++ を使用して説明してもらえますか?
6 に答える
ファサードパターン:複雑なサブシステムまたは一連のインターフェースに統一された単純化されたインターフェースを提供します。複雑なサブシステムからクライアントを同時に切り離す、より高いレベルのインターフェースを提供します。
あなたが理解するのを助けるための例..タクシー運転手。キャブドライバーに「TakemetoPointX」(統一された簡略化された高レベルのインターフェース)と指示すると、一連のアクション(キーを回す、ギアを変更する、アクセルを押すなど)を開始してタスクを実行します。彼は、基盤となるサブシステム(ギアボックス、エンジンなど)の複雑さを抽象化して、それらについて心配する必要がないようにします。ドライバーはまた、実際に使用されている車両からあなたを切り離します...あなたは車と直接インターフェースしません。あなたは彼にメルクを与える可能性がありますが、ドライバーへのインターフェースはまだTakeMeTo(X)..あなたは特定のモデル/車のメーカーに縛られていません。
実際の例では、サードパーティのコンポーネントまたはライブラリとインターフェイスするファサードがあります。コードを特定のベンダーに依存させたくないので、分離するためにファサードインターフェイスを導入します。また、このインターフェイスを簡略化します。たとえば、ファサードインターフェイスにはSendData(string)というメソッドがありますが、内部的には、実装はタスクを実行するために特定の順序でm個のサブパッケージに対してn個のメソッドを呼び出す場合があります。これは、ウィキペディアページの図が示すものです。
例:例をC ++に翻訳し、それを小さく保つ
sResource = LWCPPSimple::get("http://www.perl.org")
ここで、C++の架空のWWW用ライブラリは、プロトコル、ネットワーク、および問題の解析の側面を統合するファサードであり、リソースのフェッチという主な焦点に集中できます。getメソッドは、HTTP、FTP、その他のさまざまなプロトコル、要求/応答、接続管理などの複雑さ(場合によっては醜い)を隠したり、カプセル化したり、1か所にまとめたりします。 get()を2倍高速にする方法で、パフォーマンス上の利点を無料で得ることができます。クライアントコードを変更する必要はありません。
class Engine
{
public:
void Start() { }
};
class Headlights
{
public:
void TurnOn() { }
};
// That's your facade.
class Car
{
private:
Engine engine;
Headlights headlights;
public:
void TurnIgnitionKeyOn()
{
headlights.TurnOn();
engine.Start();
}
};
int Main(int argc, char *argv[])
{
// Consuming facade.
Car car;
car.TurnIgnitionKeyOn();
return 0;
}
C# の例で検索と置換を行いました。これは役に立たないかもしれません。C++ を理解していれば、同じ構造とキーワード (クラス、関数、名前空間、パブリックなど) を使用するため、C# を理解できるはずだからです。
// "Subsystem ClassA"
#include <iostream>
class SubSystemOne
{
public:
void MethodOne()
{
std::cout << " SubSystemOne Method" << std::endl;
}
}
// Subsystem ClassB"
class SubSystemTwo
{
public:
void MethodTwo()
{
std::cout << " SubSystemTwo Method" << std::endl;
}
}
// Subsystem ClassC"
class SubSystemThree
{
public:
void MethodThree()
{
std::cout << " SubSystemThree Method" << std::endl;
}
}
// Subsystem ClassD"
class SubSystemFour
{
public:
void MethodFour()
{
std::cout << " SubSystemFour Method" << std::endl;
}
}
// "Facade"
class Facade
{
SubSystemOne one;
SubSystemTwo two;
SubSystemThree three;
SubSystemFour four;
public:
Facade()
{
}
void MethodA()
{
std::cout << "\nMethodA() ---- " << std::endl;
one.MethodOne();
two.MethodTwo();
four.MethodFour();
}
void MethodB()
{
std::cout << "\nMethodB() ---- " << std::endl;
two.MethodTwo();
three.MethodThree();
}
}
int Main()
{
Facade facade = new Facade();
facade.MethodA();
facade.MethodB();
return 0;
}
ある意味では、Facade は、隠された何かと対話したいクライアントのための単なる API です。
Facade は、C++ で実装されているもの、または単純に API よりも複雑なもののために単純な C API を公開する場合に役立ちます。または、ライブラリが多数の反復的な更新を行う必要があり、クライアントへの影響をできるだけ少なくしたい場合に、クライアントとライブラリの間に固定された障壁を取得します。たとえば、C ベースのライブラリを内部で C++ などに更新する必要がある場合、またはまったく別のものに交換する必要がある場合、Facade はクライアントにとって適切な中間層です。
class A {
private B b; // Class A uses Class B, the "interface"
public int f() { return b.g(); }
};
class B {
private C c; // class B uses class C, a "subsystem"
private ... ...; // other subsystems can be added
public int g() { c.h(); return c.i(); }
};
class C { // a subsystem
public void h() { ... }
public int i() { return x; }
};
クラス A はメソッドを直接使用したり、クラス C やクラス B に含まれる他のサブシステムの状態に直接影響を与えたりすることはありません。サブシステムの数は重要ではないため、ここではサブシステムを 1 つだけ示します。