2013年9月16日月曜日

[D]デザインパターン修行:Builderパターン

Builderパターンは複雑なオブジェクトの生成を抽象化するデザインパターン。

  • Builderインターフェース
    • オブジェクトの組み立てに使うメソッドを定義する
  • Directorクラス
    • Builderのメソッドを適切な順序で使ってオブジェクトを組み立てる
  • ConcreteBuilderクラス
    • Builderで定義したメソッドを実装する

BuilderパターンをD言語で書いてみます。

/* builderパターン */

import std.algorithm;
import std.string;
import std.stdio;

interface DocBuilder {
  void makeTitle(string title);
  void addContent(string content);
  string getResult();
}

class HtmlBuilder : DocBuilder {
  string title;
  string[] contents;

  override void makeTitle(string title) {
    this.title = title;
  }

  override void addContent(string content) {
    this.contents ~= content;
  }

  override string getResult() {
    string fmt = "<html><head><title>%s</title></head><body>%s</body></html>";
    string c = reduce!((a, b) => a ~ "<a>%s</a>".format(b))("", contents);
    return fmt.format(title, c);
  }
}

class TextBuilder : DocBuilder {
  string title;
  string[] contents;

  override void makeTitle(string title) {
    this.title = title;
  }

  override void addContent(string content) {
    this.contents ~= content;
  }

  override string getResult() {
    string list = "";
    foreach(s; contents) {
      list ~= "- " ~ s ~ "\n";
    }
    return "* " ~ title ~ "\n" ~ list;
  }  
}

class Director {
  private DocBuilder builder;

  this(DocBuilder builder) {
    this.builder = builder;
  }

  string construct(string title, string[] contents) {
    builder.makeTitle(title);
    foreach(c; contents) {
      builder.addContent(c);
    }
    return builder.getResult();
  }
}

void main() {
  auto d1 = new Director(new HtmlBuilder());
  writeln(d1.construct("AAA", ["hello", "world"]));
  auto d2 = new Director(new TextBuilder());
  writeln(d2.construct("AAA", ["hello", "world"]));
}
> dmd builder.d
> ./builder
<html><head><title>AAA</title></head><body><a>hello</a><a>world</a></body></html>
* AAA
- hello
- world

0 件のコメント:

コメントを投稿