今回はデザインパターンの一つであるFacade(ファサード)パターンについて解説します。Facadeとは「建物の正面」を意味する言葉で、そこから転じて「窓口」のような意味合いで捉えると理解しやすい言葉です。
図1 タイトルスライド「Facadeパターン」
パターンの定義
Facadeパターンの定義は、次のように整理されます。
図2 Facadeパターンの定義
サブシステム内に存在する複数のインタフェースに1つの統一インタフェースを与える。 Facadeパターンはサブシステムの利用を容易にするための高レベルインタフェースを定義する。
この定義文には「サブシステム」「インタフェース」「統一インタフェース」「高レベルインタフェース」といった専門用語が含まれています。それぞれの言葉が指している意味を、順番に見ていきます。
サブシステムとは
ここでいう「サブシステム」とは、C#でいえば1つのプロジェクト(アセンブリ、DLL)に相当します。システム開発、特に規模の大きいシステムでは、受注・発注・在庫といった機能単位でプロジェクトを分割し、担当者を分けて設計・実装することがあります。1つのシステムを複数のサブシステムに分割して構築することは、システムの複雑さを軽減するのに役立ちます。
図3 サブシステムの分割イメージ(Main/受注/発注/在庫/データ連携)
図4 受注・発注・在庫のように機能単位でサブシステムを分割する例
受注・発注・在庫のような業務単位のほかにも、何らかの装置に対する通信をまとめた1つのプロジェクトをサブシステムとして切り出すケースや、Amazonのシステムや外部クラウドサービスとのデータ連携だけを担当する専用のサブシステムを作るケースもあります。
図5 外部サービスとのデータ連携専用のサブシステムを作る例
インタフェースとは
定義の中に出てくる「インタフェース」は、C#のキーワードとしてのinterfaceではなく、APIという意味で使われています。単純に言えば「メソッドの集まり」であり、そのシステムが外部に公開している、入出力とメソッド名だけが分かっている呼び出し可能なメソッド群のことを指します。
図6 定義文中の「インタフェース」に注目する
「複数のインタフェースに1つの統一インタフェースを与える」というのは、複数のメソッド群に対して、別の1つのメソッド群を新たに与えるという意味になります。
高レベルインタフェースを定義する
図7 定義文の前半部分(複数インタフェースへの統一インタフェースの付与)
図8 定義文の後半部分(サブシステム利用を容易にする高レベルインタフェース)
つまりFacadeパターンとは、クライアント(サブシステムを利用する側)から見たときに、サブシステムを簡単に使えるように簡略化されたメソッド群を持つオブジェクトを1つ用意しましょう、という考え方のパターンです。
参考コード:Facadeパターンのイメージ
このレクチャーの動画には実コードは登場しませんが、ここまでの定義をC#のコードに落とし込むと、次のようなイメージになります。受注・発注・在庫という3つのサブシステムのクラスをそれぞれ直接呼び出すのではなく、それらをまとめて呼び出す高レベルなFacadeクラスを用意します。
// 各サブシステム(受注・発注・在庫)のクラス
public class 受注システム
{
public void 受注登録(string 商品コード, int 数量)
{
// 受注に関する複雑な処理
}
}
public class 発注システム
{
public void 発注登録(string 商品コード, int 数量)
{
// 発注に関する複雑な処理
}
}
public class 在庫システム
{
public void 在庫確認(string 商品コード)
{
// 在庫確認に関する複雑な処理
}
public void 在庫更新(string 商品コード, int 数量)
{
// 在庫更新に関する複雑な処理
}
}
// サブシステムの利用を容易にする高レベルインタフェース(Facade)
public class 受発注Facade
{
private readonly 受注システム _juchu = new();
private readonly 発注システム _hacchu = new();
private readonly 在庫システム _zaiko = new();
// クライアントはこのメソッド1つを呼ぶだけでよい
public void 商品を注文する(string 商品コード, int 数量)
{
_zaiko.在庫確認(商品コード);
_juchu.受注登録(商品コード, 数量);
_hacchu.発注登録(商品コード, 数量);
_zaiko.在庫更新(商品コード, 数量);
}
}
// クライアント側のコード
var facade = new 受発注Facade();
facade.商品を注文する("A-001", 10);
クライアント側は、受注・発注・在庫という3つのサブシステムの詳細な呼び出し順序を知らなくても、受発注Facadeクラスの商品を注文するメソッドを1つ呼び出すだけで済みます。これが「サブシステムの利用を容易にするための高レベルインタフェースを定義する」というFacadeパターンの定義そのものです。
まとめ
Facadeパターンは、複数のサブシステム(複数のインタフェース=メソッド群)に対して、それらをまとめて簡単に使えるようにする統一インタフェース(高レベルインタフェース)を1つ提供するパターンです。次回以降のレクチャーでは、このFacadeパターンを実際のC#コードで実装していきます。
■非公開コース「C#14新機能」プレゼント:
非公開コース「C#14新機能」(80分)をご覧になりたい方は
こちらからURLとパスワードを発行していますので、ご覧になってみてください。
非公開コース「C#14新機能」を観る
A01_はじめに
A02_プロジェクトの作成
B01_配列とは
B02_配列の生成とアクセス
B03_生成と同時に値を設定する
B04_型推論による生成
B05_メソッドの引数などにする場合の注意点
B06_Length
B07_IndexOfでの検索
B08_FindIndexでの検索
B09_Find
B10_Exists
B11_FindAllとFindLast
B12_誤ったコピー
B13_Array.Copy
B14_範囲指定のコピー
B15_Resize
C01A_ArrayList
C02_List
C03_List 動的な要素の変更
C04_Listのコンストラクタ
C05_Listのコンストラクタ_Capacity
C06_ListTからArrayクラスのメソッドが呼ばれている
D01_コレクションインタフェースとは
D02_異なるコレクションクラスに互換性を持たせる
D03_インタフェースの階層構造
D04_クライアントができる操作を制限させる
D05_クライアントができる操作を制限させる_後半
D06_Enumerableの拡張メソッドに関して
D07_ReadOnly系のコレクションインタフェース
D08_AsReadOnly
D09_ToListでコピーする
D10_ListTはprivateで使う
■非公開コース「C#14新機能」プレゼント:
非公開コース「C#14新機能」(80分)をご覧になりたい方は
こちらからURLとパスワードを発行していますので、ご覧になってみてください。
非公開コース「C#14新機能」を観る