デザインパターンFacadeについて勉強した

facadeとは

正面、間口というような意味の英語です。

何か複雑な手順のコードがあったとします。
クラスやメソッドの呼び出し順にルールがあったり、何か複雑な計算だったりです。
全体でそのコードが一度しか登場しないとしても、コードの可読性を考慮するとその複雑な手順に名前をつけてメソッドとして一塊にしておくべきです。
そうすれば複雑なコードを読み解かなくても、メソッド名からこの部分は何をしているのかが読み取れます。
当然もう一度同じ処理をしたいならそのメソッド名一つを書くだけで良くなります。

このように複雑な(簡単でも)一連の手順をメソッドにまとめて、一つのメソッドを呼ぶだけで全てやってくれるようにすることをfacadeパターンと呼びます。

・・・そもそもこれはメソッドや関数の存在意義そのままではないでしょうか。

コード例

facadeパターンは要するにメソッドの実装のことだという認識をしたのでこれがfacadeパターンだ!というような例は思いつきませんでした。

今回は自分の生年月日を入力すると現在の年齢を教えてくれる窓口を作ってみます。
使用者であるMainクラスは、メソッドをたった一つ呼ぶことで、複雑なコードや内部で使われるメソッドのルールを全く意識せずに機能が実現できていることがわかるかと思います。

AgeFacadeクラス

public class AgeFacade {

	private AgeFacade() {

	}

	public static void agePrint() {
		Calendar now = Calendar.getInstance();
		Calendar birthday = Calendar.getInstance();
		int year = scanNumber("生まれた年を入力してください");
		int month = scanNumber("生まれた月を入力してください");
		int day = scanNumber("生まれた日を入力してください");
		birthday.set(year,month,day);

		Calendar age = Calendar.getInstance();
		age.setTimeInMillis(now.getTimeInMillis()-birthday.getTimeInMillis());

		System.out.println(String.format(
				"あなたの年齢は%d歳と%dヶ月%d日です",
				age.get(Calendar.YEAR)-1970,
				age.get(Calendar.MONTH)+1,
				age.get(Calendar.DATE)));
	}

	private static int scanNumber(String message) {
		Scanner scanner = new Scanner(System.in);
		String text = "";
		while(!text.matches("\\d+")) {
			System.out.print(message+":");
			text = scanner.nextLine();
		}
		return Integer.parseInt(text);
	}
}

年齢を教えてくれる窓口です。
コンストラクタはprivateになっているので呼び出せません。

たった一つ、agePrintメソッドを呼び出すだけで全ての処理が完結します。



現在の時刻、入力する年月日の、それぞれCalendarクラスのインスタンスを作ります。
Calendarクラスはnewによるインスタンス化ができませんが、agePringメソッドの呼び出し元はそのようなルールは一切気にする必要はありません。
年月日の入力はscanNumberメソッドで行っています。
各カレンダーを使って計算し、現在の年齢を算出しています。
最後のprintlnでは年の値から1970引いています。
この1970引かなければいけないことも呼び出しもとは気にする必要はありません。

実装

public class Main {

	public static void main(String[] args) {
		AgeFacade.agePrint();
	}
}

agePrintという窓口へ行き、「私の年齢を教えてください」というだけで難しいことは何も考えずに年齢を知ることができます。

実行

生まれた年を入力してください:2000
生まれた月を入力してください:1
生まれた日を入力してください:2
あなたの年齢は21歳と5ヶ月21日です

特徴

特徴というかメソッドの使い方にもなりますが、プログラムは1つのメソッド(コンストラクタ)に全て書き込むべきではありません。
ほどほどの行数で分割して、何をしているかが一目でわかるような名前を付けるべきです。

まとめ

メソッドの存在するjava言語では基本中の基本となるパターンかと思います。