読者です 読者をやめる 読者になる 読者になる

【デザインパターン】Builder

デザインパターン

どんなもの?

  • あるオブジェクトの建築過程(construction process)と表現方法(representation)を分離することで、柔軟に変更できるソフトを目指す

どんなときに使う?

  • 複雑なオブジェクトを複数種類作成したいとき

典型的な構成要素

  • Director
    • ConcreteBuilderの実態に関係なく、Builderに提供されているインターフェースのみを使用し、建築する。
  • Builder
    • 建築過程の書く関数のインターフェースを定める
  • ConcreteBuilder
    • Builderが定めたインターフェースを実装する
  • Client

    コード

#include <iostream>
#include <string>
#include <map>

using namespace std;

class Builder{
public:
  virtual void makeHeader(string &text) = 0;
  virtual void makeMainText(string maintext, string &text) = 0;
  virtual void makeFooter(string &text) = 0;
};

class PlainTextBuilder: public Builder{
  void makeHeader(string &text){
    text += "-----------\n";
  }
  void makeMainText(string maintext, string &text){
    text += "|" + maintext + "|\n";
  }

  void makeFooter(string &text){
    text += "----Fin----\n";
  }
};

class GorgousTextBuilder: public Builder{
  void makeHeader(string &text){
    text += "***********\n";
  }
  void makeMainText(string maintext, string &text){
    text += "*" + maintext + "*\n";
  }

  void makeFooter(string &text){
    text += "****Fin****\n";
  }
};

class Director{
public:
  Director(){}

  void construct(void){
    builder -> makeHeader(text);
    builder -> makeMainText("本文",text);
    builder -> makeFooter(text);
  }

  const string& getText(void){
    return text;
  }

  void setBuilder(Builder* builder){
    this->builder = builder;
  }
private:
  Builder *builder;
  string text;
};

int main(void){

  string state = "plain";
  Director director;
  if(state=="plain"){
    PlainTextBuilder plain;
    director.setBuilder(&plain);
  }else{
    GorgousTextBuilder gorgous;
    director.setBuilder(&gorgous);
  }

  director.construct();
  string text = director.getText();
  cout << text << endl;
}