ねらい
- 複数クラスからなるサブシステムに窓口を設け、簡単に使えるようにする
モチベーション
-
システムをサブシステムに小分けにすることで、複雑性を下げることができる
-
サブシステムはクラスと似ている
- インタフェースを提供する
- なにかをカプセル化する
-
- クライアント-サブシステム間や、サブクラス同士の依存を最小化したい
- 単一の窓口オブジェクト、facadeを設けることでこれを実現する
-
facadeは高レベルなインタフェースを提供する
- あまり細かなことはできないが、大抵はこれで充分
- 使うのが簡単
-
細かな操作を行いたい場合は、サブシステムを構成するクラス群を直接操作する
- 強力でなんでもできる低レベルなインタフェース
- 使うのが大変
つかいどころ
-
複雑なサブシステムについて、簡潔なインターフェースを提供したい
- 何でもできるのが使いやすいとは限らない
-
クライアントコードと、サブシステムを構成するクラス群との間に、多くの依存関係が存在する
- Facadeを通してアクセスさせることで依存を切り離す
- サブシステム間の依存関係を完結にしたい
登場人物
-
Facade
- クライアントコードから要求を受け取る
- 要求について、どのsubsystem classが責務を持っているか知っている
- 適切なsubsytem classesに処理を委譲する
-
subsystem classes
- サブシステムの機能を実装する
Facade
から委譲された仕事を全うする-
Facade
のことは認知しない- Mediatorパターンとの大きな違い
結果
- クライアントがサブシステムを利用するにあたり、直接利用するクラスが減り、使いやすくなる
-
クライアントとサブシステムとが疎結合になる
- それぞれ独立して開発されていく場合はとくに重要
- コンパイル時の依存性が減少するため、再コンパイルが減るのもうれしい
- クライアントコードには、「簡単に使えること」と「何でもできること」のトレードオフを提供できる
実装にあたり考えるべきこと
-
クライアント-サブシステム間を疎結合にする
-
Facade
を抽象クラスにする- サブシステムの実装ごとに
ConcreteFacade
を用意 -
挿げ替えるのが容易になる
- クライアントはどの
ConcreteFacade
を使っているのか認知しない
- クライアントはどの
- サブシステムの実装ごとに
-
Facade
オブジェクトにsubsystem classesのオブジェクトを集約させる- subsytem classesオブジェクトを挿げ替えることで、別実装に挿げ替えることができる
-
-
サブシステムを構成するクラス群にアクセシビリティを設ける
- サブシステムとクラスとは似ている
- サブシステムにとってのクラスは、クラスにとってのメンバに相当する
-
クラスを構成するメンバにアクセシビリティがあるように、
サブシステムを構成するクラスにもアクセシビリティを設けることは有用である- C++の名前空間など
-
Facade
クラスは当然”public”に属する- サブシステムの低レベルインターフェースを利用する際に、
直接アクセスするsubsystem classesも”public”に属する
- サブシステムの低レベルインターフェースを利用する際に、
【補強】用例
-
例) Laravelの
\DB
ファサード-
Facadeパターンを享受するケース:
\DB::someOperation();
- デフォルトのコネクションに処理を委譲する
\DB
はDatabaseManager
オブジェクトに処理を委譲しているので、DatabaseManager
がFacadeパターンにおけるFacade
クラスにあたる- Laravel用語的には
「\DB
のクラスメソッドを呼び出しているかのようにDatabaseManager
のインスタンスメソッドを呼び出せる」
機能をFacadeと呼んでいる。言葉のずれがややこしい
-
サブシステムの構成クラスを直接操作するケース:
$connection = \DB::connection('connection_name');
Connection
オブジェクトを取得し直接操作する。デフォルト以外のコネクションを使うときに呼び出す
-
関連するパターン
-
AbstractFactory
-
サブシステムを構成するオブジェクトを作らせる
- 作ったオブジェクトを
Facade
が集約する
- 作ったオブジェクトを
-
-
Mediator
- サブシステムを構成するクラス群において、スター型の依存構造をつくり、真ん中に陣取るヤツ。
また、そのパターン - 既存のクラスの機能を抽象化するという点ではFacadeと似ている
-
異なる点
-
Facade
- クライアントとサブシステムとの間に立ち、リクエストを仲介する
- サブシステムを構成するクラスは、
Facade
の存在を知らない
-
Mediator
- サブシステムを構成するクラス同士の連絡を仲介する
- サブシステムを構成するクラスは、
Mediator
の存在を知っている
-
- サブシステムを構成するクラス群において、スター型の依存構造をつくり、真ん中に陣取るヤツ。
-
Singleton
Facade
オブジェクトはふつう1つでよいのでSingletonにできる
英語
-
forgo
-
諦める、控える
- 何かを切り捨てる感じか
- 納期の都合上、要求を取捨選択して要件を小さくするときとか
-