一. 概述
Builder 模式要解決的問題是:當我們要創建的對象很復雜的時候(通常是由很多其他的對象組合而成),我們要要復雜對象的創建過程和這個對象的表示(展示)分離開來,這樣做的好處就是通過一步步的進行復雜對象的構建,由於在每一步的構造過程中可以引入參數,使得經過相同的步驟創建最後得到的對象的展示不一樣。
二. 舉例
KFC 與 Mcdonalds 的漢堡生成過程大致都是一樣的,假設分為4個步驟;
但是 KFC 與 Mcdonalds 的漢堡味道有所差別,主要是在每一步的細節上有所不同。
顧客要吃漢堡並不關心具體的生產步驟,其實漢堡店也不關心,因為數百年來,這些步驟者是相同的,差別只在細節上。比如鹽放多少,辣椒放多少等等。
結構如下:
Builder:為最基本的生產步驟
KFCBuilder:為KFC的具體生產步驟
MCDBuilder:為Mcdonalds的具體生產步驟
Director:為指揮者,用它來控件建造過程
[cpp] //////////////////////////////////////////////////////////////////////////
//建造者
class Builder
{
public:
virtual ~Builder()
{
}
virtual void BuildSetp1() = 0;
virtual void BuildSetp2() = 0;
virtual void BuildSetp3() = 0;
virtual void BuildSetp4() = 0;
};
//KFC 具體建造者
class KFCBuilder:public Builder
{
public:
void BuildSetp1()
{
cout<<"KFC Step1:"<<endl;
}
void BuildSetp2()
{
cout<<"KFC Step2:"<<endl;
}
void BuildSetp3()
{
cout<<"KFC Step3:"<<endl;
}
void BuildSetp4()
{
cout<<"KFC Step4:"<<endl;
}
};
//Mcdonalds 具體建造者
class MCDBuilder:public Builder
{
public:
void BuildSetp1()
{
cout<<"Mcdonalds Step1:"<<endl;
}
void BuildSetp2()
{
cout<<"Mcdonalds Step2:"<<endl;
}
void BuildSetp3()
{
cout<<"Mcdonalds Step3:"<<endl;
}
void BuildSetp4()
{
cout<<"Mcdonalds Step4:"<<endl;
}
};
//////////////////////////////////////////////////////////////////////////
//指揮者
class Director
{
private:
Builder *m_pBuilder;
public:
Director(Builder *builder)
{
m_pBuilder = builder;
}
void Create()
{
m_pBuilder->BuildSetp1();
m_pBuilder->BuildSetp2();
m_pBuilder->BuildSetp3();
m_pBuilder->BuildSetp4();
}
};
//////////////////////////////////////////////////////////////////////////
//測試代碼
int main(int argc,char* argv[])
{
KFCBuilder kfc; //想吃KFC
Director director(&kfc);
director.Create();
return 0;
}
//////////////////////////////////////////////////////////////////////////
//建造者
class Builder
{
public:
virtual ~Builder()
{
}
virtual void BuildSetp1() = 0;
virtual void BuildSetp2() = 0;
virtual void BuildSetp3() = 0;
virtual void BuildSetp4() = 0;
};
//KFC 具體建造者
class KFCBuilder:public Builder
{
public:
void BuildSetp1()
{
cout<<"KFC Step1:"<<endl;
}
void BuildSetp2()
{
cout<<"KFC Step2:"<<endl;
}
void BuildSetp3()
{
cout<<"KFC Step3:"<<endl;
}
void BuildSetp4()
{
cout<<"KFC Step4:"<<endl;
}
};
//Mcdonalds 具體建造者
class MCDBuilder:public Builder
{
public:
void BuildSetp1()
{
cout<<"Mcdonalds Step1:"<<endl;
}
void BuildSetp2()
{
cout<<"Mcdonalds Step2:"<<endl;
}
void BuildSetp3()
{
cout<<"Mcdonalds Step3:"<<endl;
}
void BuildSetp4()
{
cout<<"Mcdonalds Step4:"<<endl;
}
};
//////////////////////////////////////////////////////////////////////////
//指揮者
class Director
{
private:
Builder *m_pBuilder;
public:
Director(Builder *builder)
{
m_pBuilder = builder;
}
void Create()
{
m_pBuilder->BuildSetp1();
m_pBuilder->BuildSetp2();
m_pBuilder->BuildSetp3();
m_pBuilder->BuildSetp4();
}
};
//////////////////////////////////////////////////////////////////////////
//測試代碼
int main(int argc,char* argv[])
{
KFCBuilder kfc; //想吃KFC
Director director(&kfc);
director.Create();
return 0;
}
三. 說明
1. 建造者模式,在建造順序上通常是穩定的。
2. 指揮者(Director),來隔離用戶與具體建造過程的關聯。
3. 它的好處是,客戶端不需要知道具體的建造者方法,也不用但心忘記某一步驟沒寫,這些步驟統一由Director來調用。
作者 lwbeyond