建造者模式
注:
1. 建造者模式:---流程不變------細節改變
將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
2. 建造者模式解析:
建造者模式通常包括下面幾個角色:
builder:給出一個抽象接口,以規範產品對象的各個組成成分的建造。這個接口規定要實現複雜對象的哪些部分的創建,並不涉及具體的對象部件的創建。
ConcreteBuilder:實現Builder接口,針對不同的商業邏輯,具體化複雜對象的各部分的創建。 在建造過程完成後,提供產品的實例。
Director:調用具體建造者來創建複雜對象的各個部分,在指導者中不涉及具體產品的信息,只負責保證對象各部分完整創建或按某種順序創建。
Product:要創建的複雜對象。
總結一下:
builder建造小人各部分的抽象類。概括的說,是爲創建一個Product對象的各個部件指定的抽象接口。
ConcreteBuilder具體實現如何畫出小人的頭身手腳各部分。它是具體建造者,實現builder接口,構造和裝配各個部件。
Product就是具體的小人,產品角色。
Director指揮者,用來根據用戶的需求構建小人對象。
3. 建造者模式的例子:
------麥當勞、肯德基的生產模式:工作流程可以是一種抽象的流程,具體放什麼配料、烤多長時間等細節依賴於這個抽象。
------建造一個遊戲小人:這裏建小人的‘過程’是穩定的,都需要頭身手腳,而具體建造的細節是不同的,有胖有瘦有高有矮。
------一個人活到70歲以上,都會經歷這樣的幾個階段:嬰兒,少年,青年,中年,老年。並且每個人在各個階段肯定是不一樣的呀,我覺得可以說世界上不存在兩個人在人生的這5個階段的生活完全一樣,但是活到70歲以上的人,都經歷了這幾個階段是肯定的。實際上這是一個比較經典的建造者模式的例子了。
4. 代碼實例:class Product//要創建的複雜對象產品
{
private:
vector<string> product;
public:
void add(string str)
{
product.push_back(str);
}
void show()
{
vector<string>::iterator iter=product.begin();
while(iter!=product.end())
{
cout<<*iter<<" ";
++iter;
}
cout<<endl;
}
};
class Builder//給出一個抽象接口,以規範產品對象各個組成成分建造
{
public:
virtual void builderA()=0;
virtual void builderB()=0;
virtual Product *getResult()=0;
};
class ConcreteBuilder1:public Builder//實現builder接口
{
private:
Product *product;
public:
ConcreteBuilder1()
{
product=new Product();
}
virtual void builderA()
{
product->add("one");
}
virtual void builderB()
{
product->add("two");
}
virtual Product *getResult()
{
return product;
}
};
class ConcreteBuilder2:public Builder
{
private:
Product *product;
public:
ConcreteBuilder2()
{
product=new Product();
}
virtual void builderA()
{
product->add("A");
}
virtual void builderB()
{
product->add("B");
}
virtual Product *getResult()
{
return product;
}
};
class Director//指揮者,控制建造過程,也隔離用戶和建造過程的關係
{
private:
Product *p;
public:
void construct(Builder *bd)//根據用戶的選擇建造小人
{
bd->builderA();
bd->builderB();
p=bd->getResult();
}
Product *getResult()
{
return p;
}
};
int main()
{
Director *director=new Director();
Builder *bd1=new ConcreteBuilder1();
director->construct(bd1);
Product *pbd1=director->getResult();
pbd1->show();
return 0;
}