建造者模式
模式定義
建造者模式(Builder),將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
模式動機
- 如果我們用了建造者模式,那麼用戶就只需指定需要建造的類型就可以得到它們,而具體建造的過程和細節就不需要知道了。
- 主要是用於創建一些複雜的對象,這些對象內部構建間的建造順序通常是穩定的,但對象內部的構建通常面臨着複雜的變化。
- 建造者模式是在當創建複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時適用的模式。
UML類圖
說明:
- Builder:是爲創建一個Product對象的各個部件指定的抽象接口。
- ConcreteBuilder:是具體的建造者,實現Builder接口,構造和裝配各個部件。
- Product:具體的產品角色。
- Director:指揮者,它是構建一個使用Builder接口的對象。
源碼實現
- builder.h
#include "product.h"
class Builder
{
public:
Builder();
virtual ~Builder(){}
virtual void AddPartA();
virtual void AddPartB();
Product* GetProduct();
protected:
Product* m_Product;
};
- builder.cpp
#include <iostream>
#include "builder.h"
Builder::Builder()
{
m_Product = new Product();
}
void Builder::AddPartA()
{
m_Product->AddPart("PartA");
}
void Builder::AddPartB()
{
m_Product->AddPart("PartB");
}
Product* Builder::GetProduct()
{
if(m_Product->PartsCount() > 0)
return m_Product;
else
std::cout << "產品還未組裝好" << std::endl;
}
- concretebuilder1.h
#include "builder.h"
class ConcreteBuilder1 : public Builder
{
public:
ConcreteBuilder1();
void AddPartA() override;
void AddPartB() override;
};
- concretebuilder1.cpp
#include "concretebuilder1.h"
ConcreteBuilder1::ConcreteBuilder1()
{
}
void ConcreteBuilder1::AddPartA()
{
m_Product->AddPart("Part1");
}
void ConcreteBuilder1::AddPartB()
{
m_Product->AddPart("Part2");
}
- director.h
#include "builder.h"
class Director
{
public:
Director();
void Construct(Builder* builder);
};
- director.cpp
#include "director.h"
Director::Director()
{
}
void Director::Construct(Builder *builder)
{
builder->AddPartA();
builder->AddPartB();
}
- product.h
#include <list>
#include <string>
class Product
{
public:
Product();
void AddPart(std::string part);
void Show();
int PartsCount();
private:
std::list<std::string> m_Parts;
};
- product.cpp
#include "product.h"
#include <iostream>
Product::Product()
{
}
void Product::AddPart(std::string part)
{
m_Parts.push_back(part);
}
void Product::Show()
{
std::cout << "組成部分:" << std::endl;
for(auto part : m_Parts)
{
std::cout << part << std::endl;
}
}
int Product::PartsCount()
{
return m_Parts.size();
}
- main.cpp
#include <iostream>
#include <memory>
#include "concretebuilder1.h"
#include "concretebuilder2.h"
#include "director.h"
using namespace std;
int main()
{
std::shared_ptr<Builder> builder1 = std::make_shared<ConcreteBuilder1>();
std::shared_ptr<Builder> builder2 = std::make_shared<ConcreteBuilder2>();
Director director;
director.Construct(builder1.get());
Product* product1 = builder1->GetProduct();
product1->Show();
director.Construct(builder2.get());
Product* product2 = builder2->GetProduct();
product2->Show();
return 0;
}
- 運行結果
組成部分:
Part1
Part2
組成部分:
PartX
PartY
優點
建造者模式的優點
- 使得建造代碼與表示代碼分離,由於建造者隱藏了該產品是如何組裝的,所以若需要改變一個產品的內部表示,只需要再定義一個具體的建造者就可以了。
缺點
模式的缺點