「Facade(ファザード)」ってどんなパターン?
既存のクラスを組み合わせて使う手順を外出しすることができます。Laravelなどでも使われているデザインパターンになります。
Facadeの意味
「建物の正面」、「窓口」という意味になります。
定義
サブシステム内に存在する複数インターフェース(API)に対して一つの統一インターフェース(API)を与えます。
ここで使っている「インターフェース」は「プログラミングのインターフェース」というよりは「API」という意味に近い。
Facadeパターンはサブシステムの利用を容易にするための高レベルインターフェースを定義する。
サブシステムでできることをまとめたクラスみたいなイメージです。FacadeをnewすればあとはそのFacadeクラスの中のメソッドを呼べば利用者は「何ができるのか」すぐに理解することができます。
メリット
よく使うクラスのメソッドのうち、汎用性の高い物を、publicにして開発者間で共有したりすることで、開発スピードを上げたりバグを減らしたりできます。
「共通メソッドの外出し」に関しては、ごくごく当たり前のように使われているかもしれませんが、「クラスを使う手順を外出し」しているケースは、当たり前ではないのではないでしょうかね。
また、新しく入ってきた開発者がFacadeを見るだけでどんな機能があるかを大体把握することができるので便利です。
注意点
共通メソッドの場合でも言えることですが、ファザードとして、外出しするクラスの「汎用性」には注意しましょう。汎用性を無視して外出ししまくると、使われないようなクラスがたくさん出来てしまって、後で混乱しますからね。
使い道
レガシーコードに対峙したときに、Facadeを作りながら読み込んでいくなどをするのも良いです。メモ代わりになります。
どのようにクラス設計するのか?
共通的なクラスの利用手順を定めた「Facade(ファザード)」クラスを作成します。
正直、他のデザインパターンに比べたら非常にシンプルで理解もしやすいと思います。
具体的に実装してみる。
まずは、具体的なイメージとして、下記のクラス図になります。
Main.java(メインプログラム)
1 2 3 4 5 6 7 8 9 10 |
package facade; public class Main { public static void main(String[] args) { FacadeTest facade = new FacadeTest(); System.out.println(facade.getJapanese()); } } |
FacadeTest.java(ファザードクラス)
実際に実務で使う際は「機能名Facade」(MailFacadeなど)という命名にすると良いでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package facade; /** * ファザードクラス */ public class FacadeTest { String getJapanese() { People people = new People("日本人"); Language lang = new Language("日本語"); return people.people + "は、" + lang.language + "を話します。"; } } |
Language.java(手順化対象となるクラス1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package facade; /** * 言語クラス */ public class Language { String language; Language(String language){ this.language = language; } } |
People.java(手順化対象となるクラス2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package facade; /** * 人クラス */ public class People { String people; People(String people) { this.people = people; } } |
実行結果
設計方針
まずは一部分だけやる。
全体をいきなりFacade化しなくても良い。一部分をFacade化する形でも良い。
選び方
- 手順があるもの。
Facade内は複雑化しない方が良い
あくまで窓口で理解の補助のために使うものなのであまり処理を複雑化しない方が良いです。
そのまま返す。
Facadeのメソッドでサブクラスをnewしてそのメソッドをそのままreturnする。
1 2 3 4 5 6 7 8 9 |
static class xxxFacade { static getMail(){ return new Mail().getMail(); } static getAuth(){ return new Auth().getAuth(); } } |
実装方針
staticクラスにする方法
staticクラスで呼ぶ方法。お手軽なので気軽に使う分には非常に良い方法です。レガシーシステムとかであればテストコードとかは記述していないと思うので一旦丸ごとstaticクラスに移行して直接呼ぶようにしたら改修の工数もかからないので良いです。
interface経由で呼ぶ方法
この方法ならテストコードが書きやすくなります。
また、外注する場合は先にインターフェースだけ作っておいて外注先に渡すのが良いでしょう。外注先が勝手にインターフェースを作ってしまうと後で修正するのが大変になってしまいます。
処理の手順を吸収してあげる。
例えば、「メールを送る。」だけのメソッドや「10秒遅延させてからメールを送るメソッド」を分けるなど。
メソッド名は類似メソッドがわかるように似て名前にする。
- sendMail
- sendMailDelay
例えば、などのように。プログラミングのインテリセンス機能で利用者が用途を予測できるようにする。
ドキュメントコメントはしっかり書くこと
FacadeはAPIの窓口になることが多いのでプログラミングのドキュメント機能を使って仕様書をしっかり残すようにしましょう。
- JavaDoc(Java)
- XMLコメント(C#)
インテリセンス機能などで用途が見えたりもします。
この記事へのコメントはありません。