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

builderパターンとは

builderは何かを作る、組み立てるという意味の英語です。

ブログ記事を書くときと、新聞記事を書くときでは使うツールも作業も違います。
しかしブログ記者にタイトルと本文を渡せばブログ記事が出来上がりますし、新聞記者にタイトルと本文を渡せば新聞記事が出来上がります。
依頼者は相手がどちらであっても、「これがタイトルです」「これが本文です」と同じように情報を渡すだけで完成した記事を得ることができるのです。

具体的な記事の作り方はそれぞれの記者が知っています。
依頼者は誰に依頼する時でも同じように情報を渡せば良いのです。

唯一気にするべきなのは必要な記事が欲しいときは誰に依頼すればいいのか(ブログなのか新聞なのか)だけです。
あるいは元請け人がいる場合はそれすら気にする必要もないのかもしれません。

コード例

ブログと新聞の書き分けはできませんので、コンソールに出力する記者と、ダイアログに出力する記者に仕事を依頼することにします。

Reporterクラス

public abstract class Reporter {

	public abstract void setTitle(String title) ;

	public abstract void setBody(String text) ;

	public abstract void show();
}

記者の抽象クラスです。
この人が「ブログ記者」なのか「新聞記者」なのかはたまたそれ以外なのかはまだわかりません。

記事を書くにはtitleとbody(本文)が必要です。
setTitleメソッドは依頼者からタイトルを教えてもらうためのメソッド、
setBodyメソッドは依頼者から本文を教えてもらうためのメソッドです。

showメソッドは完成した記事を見せてくれるためのメソッドです。

全て抽象メソッドとなっています。
実装するのはサブクラスの記者達です。

実装

ConsoleReporterクラス

public class ConsoleReporter extends Reporter {

	private StringBuffer buff = new StringBuffer();

	@Override
	public void setTitle(String title) {
		buff.append("<< " + title + " >>");
		buff.append("\n");
	}

	@Override
	public void setBody(String text) {
		buff.append(text);
		buff.append("\n");
	}

	@Override
	public void show() {
		System.out.println("================");
		System.out.println(buff);
		System.out.println("================");
	}
}

コンソール記者です。

buffフィールドは記事内容を保管するためのものです。

setTitleメソッドは記事にタイトル文を加えます。

setBodyメソッドは記事に本文を加えます。

showメソッドはコンソールに記事を表示します。

public class DialogReporter extends Reporter {

	private String title ;
	private String text ;

	@Override
	public void setTitle(String title) {
		this.title = title;
	}

	@Override
	public void setBody(String text) {
		this.text = text;
	}

	@Override
	public void show() {
		JOptionPane.showMessageDialog(null,text,title,JOptionPane.PLAIN_MESSAGE);
	}
}

ダイアログ記者です。

title,bodyに関しては説明は不要でしょうか。

showメソッドはダイアログを表示します。

public class Main {

	public static final String CONSOLE = "console";
	public static final String DIALOG = "dialog";

	public Main() {
		Scanner scanner = new Scanner(System.in);
		String text = "";

		while(!CONSOLE.equals(text) && !DIALOG.equals(text)) {
			System.out.print(String.format("入力してください(%s/%s):",CONSOLE,DIALOG));
			text = scanner.nextLine();
		}
		scanner.close();

		Reporter reporter ;
		if(CONSOLE.equals(text)) {
			reporter = new ConsoleReporter();
		}else {
			reporter = new DialogReporter();
		}

		reporter.setTitle("Builderパターンとは");
		reporter.setBody("builderパターンはデザインパターンの一つです");

		reporter.show();
	}

	public static void main(String[] args) {
		new Main();
	}
}

依頼者です。

コンソールから入力した内容によって、コンソール記者かダイアログ記者かどちらに依頼するかを選択します。

reporter.setTitleではタイトルを、setBodyでは本文を渡して「こんな記事を書いてください」とお願いをしています。

最後にshowメソッドでできた記事を見せてもらっています。

特徴

AbstractFactoryになんとなく似ていますが、AbstractFactoryは使っているクラスが具体的に何なのかを意識しなくていいパターンです。
対してBuilderパターンは「書きたい記事の内容」と「記事を書くための専門知識」を切り離して考えられ、依頼者側は必要なものを並べるだけで欲しいものが作れるようになります。

まとめ

例えば今書いているこの記事でも、私はWebページの知識はなくてもタイトルと本文、それにタグだけ作れば作りたい記事が書けています。
URLやHTML/CSSのような専門知識はほぼ皆無なのにです。
このように、簡単な情報を組み立てるだけで本格的なものが作れるようにするのがこのパータンです。