建造者模式(Builder Pattern):将一個複雜對象的建構與它的表示分離,使得同樣的建構過程可以建立不同的表示。建造者模式是一種對象建立型模式。通過這個定義,我們可以得出建造者是一種建立型模式,也就是說建造者模式的輸出是一個對象,也就是UML類圖中的product。
我們先看看建造者模式的UML類圖:

UML類圖中我們可以看出,建造者模式使用了聚合、繼承和依賴三種關系。第一個疑問就是為什麼要使用聚合,如果我們不使用聚合的話,我們始終得到的都是穩定的建構過程,例如我們遊戲中每個NPC都有2隻手,當我們想要我們遊戲在某些場合NPC都是一隻手的時候,我們需要對每個ConcreteBuilder中添加生成一隻手的邏輯,非常地備援。
第二個疑問就是我們為什麼使用繼承,這個問題比較好回答,因為通過這次的基礎我們可以讓每個繼承之Builder的子類都需要實作Builder中定義的純虛函數,防止某些ConcreteBuilder忘記了寫某些函數導緻缺胳膊缺腿的情況。
最後一個疑問自然也就是為什麼使用依賴,其實這個也比較好回答,因為我們要生成一個product。同時我們通過這個依賴關系能夠得出,建造者模式是在product的基礎之上進行封裝,也就是說我們不喜歡改變product的東西而是調用porduct的方法。
遊戲中會有各種log,而log往往都有公共的庫,我們使用這些log的時候不希望改變log的内部結構,僅僅是使用這種log提供的各種方法。log可以分為各種類型,例如調試資訊、錯誤資訊、警告資訊和自定義資訊等。我們希望在Windows下面每種log的顔色不一樣,友善我們檢視,在linux下面每種log的顔色一樣等。
代碼如下圖:
// MVC.cpp : 定義控制台應用程式的入口點。
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Log
{
public:
Log():m_color(0),m_size(0),m_isWriteFile(false){};
void SetSize(int size)
{
m_size = size;
}
void SetColor(int color)
{
m_color = color;
}
void WriteFile( bool value )
{
m_isWriteFile = value;
}
void PrintInfo()
{
cout<<"m_color:"<<m_color<<endl<<"m_size:"<<m_size<<endl<<"m_isWriteFile"<<m_isWriteFile<<endl;
cout<<"----------------------------"<<endl;
}
private:
int m_color;
int m_size;
bool m_isWriteFile;
};
class ILogBuider
{
public:
ILogBuider(){};
virtual ~ILogBuider(){};
virtual void SetColor() = ;
virtual void SetSize() = ;
virtual void WriteFile() = ;
};
class DLogBuiler:public ILogBuider
{
public:
DLogBuiler()
:m_product(new Log())
{}
void SetSize()
{
m_product->SetSize();
}
void SetColor()
{
m_product->SetColor();
}
void WriteFile()
{
m_product->WriteFile(true);
}
Log* GetLog()
{
return m_product.get();
}
private:
auto_ptr<Log> m_product;
};
class ELogBuiler:public ILogBuider
{
public:
ELogBuiler()
:m_product(new Log())
{}
void SetSize()
{
m_product->SetSize();
}
void SetColor()
{
m_product->SetColor();
}
void WriteFile()
{
m_product->WriteFile(true);
}
Log* GetLog()
{
return m_product.get();
}
private:
auto_ptr<Log> m_product;
};
class WDirector
{
public:
WDirector(){};
void Construct(ILogBuider* builder)
{
builder->SetColor();
builder->SetSize();
builder->WriteFile();
}
};
class LDirector
{
public:
LDirector(){};
void Construct(ILogBuider* builder)
{
builder->SetSize();
builder->WriteFile();
}
};
void main()
{
//windows;
cout<<"------------Windows-----------------"<<endl;
auto_ptr<WDirector> wDirector(new WDirector());
auto_ptr<LDirector> lDirector(new LDirector());
auto_ptr<DLogBuiler>dBuilder(new DLogBuiler());
auto_ptr<ELogBuiler>eBuilder(new ELogBuiler());
wDirector->Construct(dBuilder.get());
wDirector->Construct(eBuilder.get());
dBuilder->GetLog()->PrintInfo();
eBuilder->GetLog()->PrintInfo();
//linux
cout<<"------------Linux-----------------"<<endl;
dBuilder.reset(new DLogBuiler());
eBuilder.reset(new ELogBuiler());
lDirector->Construct(dBuilder.get());
lDirector->Construct(eBuilder.get());
dBuilder->GetLog()->PrintInfo();
eBuilder->GetLog()->PrintInfo();
}
建造者模式屬于一種建立型的模式,主要是對product進行封裝進而能适應不同的情況,同時product内部有着穩定的建立過程。