Facadeパターン

デザインパターン【C#】:Facade 02_複雑なサブシステムに対して実装する

今回から、Facadeパターンの実装例を見ていきます。あらかじめVisual Studio 2019で「Machine」と「Machine.UI」という2つのプロジェクトを用意しています。これらはこの後のレクチャーでダウンロードできるようにしておくので、実際に手元で動かしながら確認してください。

図1 ソリューション構成(Machineプロジェクトと Machine.UI プロジェクト)

「Machine」プロジェクトには Box・Camera・Fan・FanEntity・Power といった複数のクラスが用意されています。「Machine.UI」プロジェクトには画面(Form1)が1つあるだけで、こちらにはまだ何も実装していません。

図2 Machine.UI プロジェクトの Form1(現時点では何も配置していない空の画面)

Machineプロジェクト=「複雑なサブシステム」の例

この講座では、「Machine」プロジェクトを複雑なサブシステムに見立てて話を進めます。Machineは何らかの装置というイメージで、装置内部の温度を取得したり、Fan(ファン)の速度を取得したり、ファンを起動・停止したり、電源を入れたりといった操作ができるようになっています。

今回サンプルとして用意したのはこの程度の規模ですが、実際の現場ではもっとクラスの数が多く、もっとごちゃごちゃとしていて「何がどうなっているのかよく分からない」ような、より複雑なサブシステムになっていると想定してください。それでも今回のサンプルだけでも、「どのクラスを」「どういう手順で」使えばいいのか迷うには十分な状態になっています。

図3 Box.cs 内部温度・外部温度を取得するクラス

namespace Machine
{
    public class Box
    {
        private Random _random = new Random();
 
        public int GetInternalTemperature()
        {
            return _random.Next(10, 80);
        }
 
        public int GetExternalTemperature()
        {
            return _random.Next(10, 80);
        }
    }
}

 

図4 Camera.cs 撮影を行うクラス

namespace Machine
{
    public class Camera
    {
        public void Take()
        {
        }
    }
}

 

図5 Fan.cs ファンの回転数取得・起動・停止を行うクラス

namespace Machine
{
    public class Fan
    {
        private Random _random = new Random();
 
        public FanEntity GetSpin(int fanId)
        {
            return new FanEntity(fanId, _random.Next(0, 3000));
        }
 
        public void Start(int fanId)
        {
        }
 
        public void Stop(int fanId)
        {
        }
    }
}

画面側からMachineを参照する

Machine.UI プロジェクトの参照設定で Machine プロジェクトを追加し、UI側のコードから Machine プロジェクトのクラスを見られる状態にしておきます。

図6 参照マネージャーで Machine プロジェクトを参照に追加する

この状態で Form1_Load メソッドの中に「Machine.」と入力してみると、Box・Camera・Fan・FanEntity・Power…といったクラスがずらっとインテリセンスに表示されます。

図7 「Machine.」と入力すると多数のクラスが一覧表示される

ここで「どれを使えばいいのか」「どういう手順で使えばいいのか」がぱっと見て分からない状態になっているのが分かると思います。

試しにFanクラスを使ってみる

試しにFanクラスを1つ使ってみます。Fanクラスをnewし、「.」と入力するとGetSpin・Start・Stop等のメソッドが表示され、GetSpinには「int fanId」という引数が必要なことがツールチップで分かります。

図8 fan.GetSpin(int fanId) のシグネチャがツールチップで表示される

fanIdには適当に 4 を渡してみると、戻り値としてFanEntityが返ってくることが確認できます。

図9 Fanクラスを生成し GetSpin(4) を呼び出した最終的なコード

private void Form1_Load(object sender, EventArgs e)
{
    var fan = new Machine.Fan();
    FanEntity entity = fan.GetSpin(4);
}

まとめ:使う側に知識が必要という問題

このように、今は画面(UI)側から直接Machineプロジェクトのクラスを使っていますが、これだと使う側にちゃんとした知識がないと実装できません。「Fanクラスをnewして、GetSpinを呼んで…」といった手順そのものを、使う側が理解していなければならないからです。もし手順がもっと複雑だったら、「どういう順番で何を呼べばいいのか」がさらに分かりづらい状態になってしまいます。

次回以降、この「使う側が複雑なサブシステムの内部を知らないと使えない」という問題を、Facadeパターンでどう解消していくかを見ていきます。

C#

■非公開コース「C#14新機能」プレゼント:
非公開コース「C#14新機能」(80分)をご覧になりたい方は
こちらからURLとパスワードを発行していますので、ご覧になってみてください。
非公開コース「C#14新機能」を観る

参考にした書籍

実戦で役立つ C#プログラミングのイディオム/定石&パターン
プログラミングC# 第8版

オブジェクト指向
ジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技
  すばらしい本です。オブジェクト指向が詰まっています。

オブジェクト脳のつくり方―Java・UML・EJBをマスターするための究極の基礎講座
  サンプルコードはjavaですが,最初にオブジェクト指向に目覚めるのに最適な本です。

Head Firstオブジェクト指向分析設計 ―頭とからだで覚えるオブジェクト指向の基本
  マンガみたいな感じで読めて,オブジェクト指向について学べます。  

Clean Code アジャイルソフトウェア達人の技
Clean Architecture 達人に学ぶソフトウェアの構造と設計
Adaptive Code ~ C#実践開発手法
.NETのエンタープライズアプリケーションアーキテクチャ
実装パターン
  廃盤のため異常に高くなりすぎなので,様子を見た方がいい気がします。一万円のボリュームがあるかどうかは微妙です。

オブジェクト指向でなぜつくるのか
レガシーコード改善ガイド
リファクタリング 既存のコードを安全に改善する

デザインパターン
オブジェクト指向における再利用のためのデザインパターン
オブジェクト指向のこころ
Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本

ドメイン駆動開発
エリック・エヴァンスのドメイン駆動設計
実践ドメイン駆動設計
ドメイン駆動
現場で役立つシステム設計の原則
エンタープライズアプリケーションアーキテクチャパターン