在做面向對象的軟件開發時我們往往想達到更高的代碼可複用性和更合理的軟件顆粒度。
根據《設計模式——可複用面向對象軟件的基礎》所說:“你必須找到相關的對象,以適當的顆粒度將他們迴歸類,再定義類的接口和繼承層次,建立對象之間的基本關係。你的設計應該對手頭的問題有針對性,同時對將來的問題和需求也要有足夠的通用性。”
內行的設計者知道:不是解決任何問題都要從頭做起。他們更願意複用以前使用的解決方案。這些重複的模式方案解決特定的問題,使得面向對象的設計更靈活、優雅,最終複用性更好。它們幫助設計者將新的設計建立在以往的工作基礎上,複用以往的成功設計方案。一個熟悉這些設計模式的設計者不需要再去發現它們,而能夠立即將他們應用於設計問題中。
本系列文章主要參考文獻爲——設計模式,可複用面向對象軟件的基礎(Design Patterns Elements of Reusable Object-Oriented SoftWare Erich.),內部代碼基本用C++語言編寫。
彙總鏈接:23種設計模式C++實現——概要(索引彙總)
文章目錄
摘要
本章主要說明建造者模式,該設計模式主要意圖是:將一個複雜對象的構建與它的表示分離,使同樣的構建過程可以創建不同的表示。
主要參與者
該設計模式的參與者有四個,分別是:
- Builder 抽象構造者,創造Product各個部件的抽象接口;
- ConcreteBuilder 具體構造者,創造Product各個部件的具體實現接口;
- Director 指導者,該類引導Builder來實現一個產品構造的成體流程;
- Product 產品,表示被構造的複雜對象;
實施流程與具體實現
總體流程
- 客戶創建Director對象,並通過Director對想要的Builder對象配置;
- 生成產品部件;
- 返回各部件組合成的產品總成;
具體實現代碼
接下來我們通過一個實例代碼來說明具體實現:
產品基類
#include <string>
#include <stdio.h>
using namespace std;
//產品基類
class Car
{
public:
//獲取產品部件函數
string GetEngine() {return m_engine;}
string GetGearBox() {return m_gearbox;}
string GetChassis() {return m_chassis;}
//設置產品部件函數
void SetEngine(string engine){m_engine = engine;
printf("Creat %s.\n",engine.c_str());}
void SetGearBox(string gearbox){m_gearbox = gearbox;
printf("Creat %s.\n",gearbox.c_str());}
void SetChassis(string chassis){m_chassis = chassis;
printf("Creat %s.\n",chassis.c_str());}
private:
string m_engine;
string m_gearbox;
string m_chassis;
};
產品子類(Product)
//寶馬車產品
class BMWCar: public Car
{
public:
BMWCar(){printf("Start build BMW.\n");}
};
//奔馳車產品
class BenzCar: public Car
{
public:
BenzCar(){printf("Start build Benz.\n");}
};
抽象建造者類(Builder)
//抽象建造者類
class CarBuilder
{
public:
virtual Car *BuildCar(){} //造整車
virtual void BuildEngine(){} //造引擎
virtual void BuildGearBox(){} //造變速箱
virtual void BuildChassis(){} //造底盤
};
具體建造者類(ConcreteBuilder )
//具體寶馬建造者類
class BMWCarBuilder: public CarBuilder
{
public:
BMWCarBuilder(){
m_car = new BMWCar();
}
void BuildEngine(){
m_car->SetEngine("BMW Engine.");
}
void BuildGearBox(){
m_car->SetGearBox("BMW GearBox.");
}
void BuildChassis(){
m_car->SetChassis("BMW Chassis.");
}
Car *BuildCar(){
return m_car;
}
private:
Car *m_car;
};
//具體奔馳建造者類
class BenzCarBuilder: public CarBuilder
{
public:
BenzCarBuilder(){
m_car = new BenzCar();
}
void BuildEngine(){
m_car->SetEngine("Benz Engine.");
}
void BuildGearBox(){
m_car->SetGearBox("Benz GearBox.");
}
void BuildChassis(){
m_car->SetChassis("Benz Chassis.");
}
Car *BuildCar(){
return m_car;
}
private:
Car *m_car;
};
指導者(Director)
//Director 指導者
class CarDirector
{
public:
Car *ConstructCar(CarBuilder *carBuilder){
carBuilder->BuildEngine();
carBuilder->BuildGearBox();
carBuilder->BuildChassis();
printf("Car build finished.\n");
return carBuilder->BuildCar();
}
};
用戶(Client)
#include "carbuilder.h"
int main(int argc, char *argv[])
{
//Client用戶
CarDirector *carDirector = new CarDirector();
Car *bmwCar = carDirector->ConstructCar(new BMWCarBuilder());
Car *benzCar = carDirector->ConstructCar(new BenzCarBuilder());
delete bmwCar;
delete benzCar;
delete carDirector;
}
運行結果
補充說明
本篇博客在完成過程中對於建造者模式有了不一樣的理解,可以捕捉到一些建造者模式的精髓,該模式在創建ConcreteBuilder的時候其實與之前所寫的工廠模式有一些相同之處,讓我覺得有一絲閃閃發光的是Director類,通過這個類來指導一個簡單的工廠模式按照一定流程完成一個產品的加工,Director就像是一個自動化產線,把各個零配件組裝裝配最終完成一個產品。
本篇博客中的代碼均已通過編譯,如有Bug,請提出寶貴意見~