面試必備之建造者設計模式

一、定義

    GOF定義:將一個複雜對象的構造與它的表示分離,使同樣的構建過程可以創建不同的表示,這樣的設計模式被稱爲建造者模式。
    Builder模式也叫
建造者模式或者生成器模式
,是由GoF提出的23種設計模式中的一種。Builder模式是一種對象創建型模式之一,用來隱藏複合對象的創建過程,它把複合對象的創建過程加以抽象,通過子類繼承和重載的方式,動態地創建具有複合屬性的對象。
    例如,計算機是由 OPU、主板、內存、硬盤、顯卡、機箱、顯示器、鍵盤、鼠標等部件組裝而成的,採購員不可能自己去組裝計算機,而是將計算機的配置要求告訴計算機銷售公司,計算機銷售公司安排技術人員去組裝計算機,然後再交給要買計算機的採購員。
    這些產品都是由多個部件構成的,各個部件可以靈活選擇,但其創建步驟都大同小異,即產品的組成部分是不變的,但每一部分是可以靈活選擇的。這類產品的創建無法用前面介紹的工廠模式描述,只有建造者模式可以很好地描述該類產品的創建。

二、角色

1.建造者(Builder):
    爲創建一個產品對象的各個部件指定抽象接口。
2.具體建造者(ConcreteBuilder):
    實現Builder的接口以構造和裝配該產品的各個部件,定義並明確它所創建的表示,並提供一個檢索產品的接口。
3.指揮者(Director):
    指揮並構造一個使用Builder接口的對象。
4. 產品(Product):
    表示被構造的複雜對象。ConcreteBuilder創建該產品的內部表示並定義它的裝配過程,包含定義組成部件的類,包括將這些部件裝配成最終產品的接口。

    ConcreteBuilder創建該產品的內部表示並定義它的裝配過程,包含定義組成部件的類,包括將這些部件裝配成最終產品的接口。

UML類圖如下:
在這裏插入圖片描述

三、實現

#include<iostream>
using namespace std;

//具體產品,房子,由門、窗、牆等組成。
class House{
private:
	string m_door;
	string m_window;
	string m_wall;
public:
	void setDoor(string door){
		this->m_door = door;
	}
	void setWindow(string window){
		this->m_window = window;
	}
	void setWall(string wall){
		this->m_wall = wall;
	}
	string getDoor(){
		cout<<this->m_door.c_str()<<endl;
		return this->m_door;
	}
	string getWindow(){
		cout<<this->m_window.c_str()<<endl;
		return this->m_window;
	}
	string getWall(){
		cout<<this->m_wall.c_str()<<endl;
		return this->m_wall;
	}
};

//Builder,提供構建房子各個組件的接口
class Builder{
public:
	virtual void builderDoor() = 0;
	virtual void builderWindow() = 0 ; 
	virtual void builderWall() = 0 ;
	virtual House* getHouse() = 0 ;
};

//指揮者,調用具體建造者構造具體的產品,和用戶直接交互,使用戶不用具體知道產品的實現細節。
class Director{
public:
	Director(){

	}
	void construct(Builder *builder){
		builder->builderDoor();
		builder->builderWindow();
		builder->builderWall();
	}
};

//具體建造者,對對象各部件進行設置
//建造公寓
class FlatBuilder:public Builder{
private:
	House* m_house;
public:
	FlatBuilder(){
		this->m_house = new House;
	}
	void builderDoor(){
		this->m_house->setDoor("flat door");
	}
	void builderWindow(){
		this->m_house->setWindow("flat window");
	}
	void builderWall(){
		this->m_house->setWall("flat wall");
	}
	House* getHouse(){
		return this->m_house;
	}
};
//建造別墅
class VillaBuilder:public Builder{
private:
	House* m_house;
public:
	VillaBuilder(){
		this->m_house = new House;
	}
	void builderDoor(){
		this->m_house->setDoor("valli door");
	}
	void builderWindow(){
		this->m_house->setWindow("valli window");
	}
	void builderWall(){
		this->m_house->setWall("valli wall");
	}
	House* getHouse(){
		return this->m_house;
	}
};
int main(){

	House *house = nullptr;
	Builder *builder = nullptr;
	Director *director = nullptr;

	//創建指揮者
	director = new Director();

	//client將建造房子的是交給指揮者,完全不用知曉怎樣建造
	builder = new FlatBuilder();
	director->construct(builder);

	//建造好,交付房子
	house = builder->getHouse();
	house->getDoor();
	house->getWindow();
	house->getWall();
	delete house;
	delete builder;
	
	builder = new VillaBuilder();
	director->construct(builder);
	house = builder->getHouse();
	house->getDoor();
	house->getWindow();
	house->getWall();
	
	delete house;
	delete builder;

	delete director;
	return 0 ;
}

四、優缺點

主要優點如下:
各個具體的建造者相互獨立,有利於系統的擴展。
客戶端不必知道產品內部組成的細節,便於控制細節風險。

缺點如下:
產品的組成部分必須相同,這限制了其使用範圍。
如果產品的內部變化複雜,該模式會增加很多的建造者類。

五、建造者模式與工廠模式的區別

Factory模式:
1、有一個抽象的工廠。
2、實現一個具體的工廠—汽車工廠。
3、A工廠生產汽車A,得到汽車產品A。
4、B工廠生產汽車B,得到汽車產品B。
這樣做,實現了購買者和生產線的隔離。強調的是結果。

Builder模式:
1、引擎工廠生產引擎產品,得到汽車部件A。
2、輪胎工廠生產輪子產品,得到汽車部件B。
3、底盤工廠生產車身產品,得到汽車部件C。
4、將這些部件放到一起,形成剛好能夠組裝成一輛汽車的整體。
5、將這個整體送到汽車組裝工廠,得到一個汽車產品。
這樣做,目的是爲了實現複雜對象生產線和其部件的解耦。強調的是過程

兩者的區別在於:
Factory模式不考慮對象的組裝過程,而直接生成一個我想要的對象。
Builder模式先一個個的創建對象的每一個部件,再統一組裝成一個對象。
Factory模式所解決的問題是,工廠生產產品。
而Builder模式所解決的問題是工廠控制產品生成器組裝各個部件的過程,然後從產品生成器中得到產品。

六、應用場景

    建造者(Builder)模式創建的是複雜對象,其產品的各個部分經常面臨着劇烈的變化,但將它們組合在一起的算法卻相對穩定,所以它通常在以下場合使用。
    創建的對象較複雜,由多個部件構成,各部件面臨着複雜的變化,但構件間的建造順序是穩定的。創建複雜對象的算法獨立於該對象的組成部分以及它們的裝配方式,即產品的構建過程和最終的表示是獨立的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章