Pythonでデザインパターンを学ぼう (Facade)
Pythonを用いてのGoFの定義した23個のデザインパターンの一つであるFacadeパターンの実装方法について解説します。
Facadeパターンは、「構造に関するデザインパターン」に分類されます。
複雑なシステムに対する簡単なインターフェースを提供します。
このパターンの目的は、システムの複雑さを隠蔽し、クライアントがより簡単にシステムを利用できるようにすることです。
Facadeパターンとは?
Facadeパターンでは、複数のサブシステムを統合して一つの統一されたインターフェースを提供するFacade(ファサード)クラスを設けます。
クライアントはこのFacadeクラスを通じて、サブシステムの複雑な内部構造を意識することなく、必要な機能を利用できます。
このパターンは、システムが多くのクラスで構成されている場合や、クラス間の依存関係が複雑な場合に特に有効です。
Facadeクラスは、クライアントからの要求を適切なサブシステムのクラスに委譲し、タスクを実行します。
Facadeパターンのクラス図
- Facade -
クライアントからの要求を受け取り、サブシステムの適切なクラスに処理を委譲 - SubSystem:
実際のタスクを実行するクラス群であり、クライアントから直接アクセスされることはない
Facadeパターンのサンプル
PythonでFacadeパターンを実装する場合、まずはサブシステムのクラスを定義します。
これらは個々の機能を持つクラスであり、Facadeクラスから利用されます。
class SubSystemA:
def sub_operation_a(self) -> str:
return "SubSystemA: Ready!\n"
class SubSystemB:
def sub_operation_b(self) -> str:
return "SubSystemB: Go!\n"
class SubSystemC:
def sub_operation_c(self) -> str:
return "SubSystemC: Finish!\n"
次に、これらのサブシステムを統合し、クライアントに対して単一のインターフェースを提供するFacadeクラスを実装します。
class Facade:
def __init__(self) -> None:
self._subsystem_a: SubSystemA = SubSystemA()
self._subsystem_b: SubSystemB = SubSystemB()
self._subsystem_c: SubSystemC = SubSystemC()
def operation(self) -> str:
results: str = "Facade initializes subsystems:\n"
results += self._subsystem_a.sub_operation_a()
results += self._subsystem_b.sub_operation_b()
results += self._subsystem_c.sub_operation_c()
results += "Facade orders subsystems to perform the action:\n"
# ここで各サブシステムの操作を実行
return results
クライアントは、Facadeクラスのoperationメソッドを呼び出すことで、複数のサブシステムにまたがる一連の操作を簡単に実行できます。
if __name__ == "__main__":
facade: Facade = Facade()
facade.operation()
client_code(facade)
この例では、Facadeクラスがクライアントからの要求を受け取り、サブシステムの適切なクラスに処理を委譲しています。
クライアントはサブシステムの内部構造や複雑さを知る必要がなく、Facadeクラスを通じて必要な操作を簡単に行うことができます。
Facadeパターンの使い道
Facadeパターンは、多数のサブシステムから構成される複雑なシステムにおいてその真価を発揮します。
システムの内部構造が複雑であっても、Facadeクラスを通じて簡単にアクセスできるようにすることで、開発の効率化と保守性の向上に貢献します。
よくある使い方としては、連携先情報が複数もあるようなシステムに向いています。
例えばECサイトの注文情報などを複数のAPIなどから取得していたり、受注情報のメインの取得先を設定していた場合は、連携している先のAPIを切り替えるロジックなどの使い道があります。
他にもRDB以外に保存先があり、データを複数のAPIに対してリクエストをする必要がある場合などです。
ただし、このパターンはオブジェクト指向の言語などのクラスについて学んだ時に、一番最初辺りに思い浮かぶパターンかと思います。
やっていることは、複数の小さな処理を一つまとめ上げているやり方に名称をつけただけです。
どれくらいの処理を一つにまとめるかというところにセンスや経験など必要になってきます。
参考資料
Discussion