1. 程式人生 > >03:建造者模式——C++實現

03:建造者模式——C++實現

目錄

一、介紹

二、應用場景

三、要點

四、樣例

五、優缺點


一、介紹

建造者模式(Builder Pattern)使用多個簡單的物件一步一步構建成一個複雜的物件。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。將一個複雜的構建與其表示相分離,使得同樣的構建過程可以建立不同的表示。

 

二、應用場景

1、需要生成的物件具有複雜的內部結構。

2、需要生成的物件內部屬性本身相互依賴。

 

一些基本部件不會變,而其組合經常變化的時候。

如:在肯德基,漢堡、可樂、薯條、炸雞翅等是不變的,而其組合是經常變化的,生成出所謂的"套餐"。

 

三、要點

將變與不變分離開。

Builder(抽象建造者):為建立一個產品物件的各個部件指定抽象介面。

ConcreteBuilder(具體建造者):實現 Builder 的介面以構造和裝配該產品的各個部件,定義並明確它所建立的表示,並提供一個檢索產品的介面。

Director(指揮者):構造一個使用 Builder 介面的物件。

Product(產品):表示被構造的複雜物件。ConcreteBuilder 建立該產品的內部表示並定義它的裝配過程,包含定義組成部件的類,包括將這些部件裝配成最終產品的介面。

 

四、樣例

1、建立產品

:建立一個 Computer 類,它可以通過組裝零件來建立。

// product.h
#ifndef PRODUCT_H
#define PRODUCT_H

#include <iostream>
#include <string>
using namespace std;

// computer
class Computer
{
public:
	void SetmCpu(string cpu) { m_strCpu = cpu; }
	void SetMainBoard(string mainboard) { m_strMainBoard = mainboard; }
	void SetRam(string ram) { m_strRam = ram; }
	void SetVideoCard(string videoCard) { m_strVideoCard = videoCard; }

	string GetCpu() { return m_strCpu; }
	string GetMainBoard() { return m_strMainBoard; }
	string GetRam() { return m_strMainBoard; }
	string GetVideoCard() { return m_strVideoCard; }

private:
	string m_strCpu;	// CPU
	string m_strMainBoard;
	string m_strRam;
	string m_strVideoCard;
};

#endif

2、建立抽象建造者:產品類準備好就可以建立Builder類了,它提供的功能用於建立電腦各個部件。

// builder.h
#ifndef BUILDER_H
#define BUILDER_H

#include "product.h"

// 建造者介面,組裝流程
class IBuilder
{
public:
        virtual void BuildCpu() = 0;
        virtual void BuildMainBoard() = 0;
        virtual void BuildRam() = 0;
        virtual void BuildVideoCard() = 0;
        virtual Computer* GetResult() = 0;        // 獲取建造後產品
};

#endif

3、建立具體建造者:有了 Builder 介面,接下來的事情就是讓 ConcreteBuilder 物件到位。在這些建造者中,我們可以指定每臺電腦要使用的部件資訊。

// concrete_builder.h
#ifndef CONCRETE_BUILDER_H
#define CONCRETE_BUILDER_H

#include "builder.h"

// ThinkPad系列
class ThinkPadBuilder : public IBuilder
{
public:
	ThinkPadBuilder() { m_pComputer = new Computer(); }
	void BuildCpu() { m_pComputer->SetmCpu("i5-6200U"); }
	void BuildMainBoard() { m_pComputer->SetMainBoard("Intel DH57DD"); }
	void BuildRam() { m_pComputer->SetRam("DDR4"); }
	void BuildVideoCard() { m_pComputer->SetVideoCard("NVDIA Geforce 920MX"); }
	Computer* GetResult() { return m_pComputer; }

private:
	Computer *m_pComputer;
};

// Yoga系列
class YogaBuilder : public IBuilder
{
public:
	YogaBuilder() { m_pComputer = new Computer(); }
	void BuildCpu() { m_pComputer->SetmCpu("i7-7500U"); }
	void BuildMainBoard() { m_pComputer->SetMainBoard("Intel DP55KG"); }
	void BuildRam() { m_pComputer->SetRam("DDR5"); }
	void BuildVideoCard() { m_pComputer->SetVideoCard("NVDIA Geforce 940MX"); }
	Computer* GetResult() { return m_pComputer; }

private:
	Computer *m_pComputer;
};

#endif

4、建立指揮者:建立一個 Director 類,讓 Create 方法接受一個 IBuilder,然後在內部呼叫相應的組裝函式。

// director.h
#ifndef DIRECTOR_H
#define DIRECTOR_H

#include "builder.h"

// 指揮者
class Director
{
public:
        void Create(IBuilder *pBuilder)
        {
                pBuilder->BuildCpu();
                pBuilder->BuildMainBoard();
                pBuilder->BuildRam();
                pBuilder->BuildVideoCard();
        }
};

#endif

5、建立客戶端

// main.cpp
#include "concrete_builder.h"
#include "director.h"
#include <string>

#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p) { delete (p); (p) = NULL; } }
#endif

int main()
{
        Director *pDirector = new Director();
        ThinkPadBuilder *pTPBuilder = new ThinkPadBuilder();
        YogaBuilder *pYogaBuilder = new YogaBuilder();

        // 組裝
        pDirector->Create(pTPBuilder);
        pDirector->Create(pYogaBuilder);

        // 獲取組裝後電腦
        Computer *pThinkPadComputer = pTPBuilder->GetResult();
        Computer *pYogaComputer = pYogaBuilder->GetResult();

        // 測試輸出
        cout << "------ThinkPad------" << endl;
        cout << "CPU:" << pThinkPadComputer->GetCPU() << endl;
        cout << "MainBoard:" << pThinkPadComputer->GetMainBoard() << endl;
        cout << "Ram:" << pThinkPadComputer->GetRam() << endl;
        cout << "VideoCard:" << pThinkPadComputer->GetVideoCard() << endl;

        cout << "------Yoga------" << endl;
        cout << "CPU:" << pYogaComputer->GetCPU() << endl;
        cout << "MainBoard:" << pYogaComputer->GetMainBoard() << endl;
        cout << "Ram:" << pYogaComputer->GetRam() << endl;
        cout << "VideoCard:" << pYogaComputer->GetVideoCard() << endl;

        SAFE_DELETE(pYogaComputer);
        SAFE_DELETE(pThinkPadComputer);
        SAFE_DELETE(pYogaBuilder);
        SAFE_DELETE(pTPBuilder);
        SAFE_DELETE(pDirector);

        getchar();
        return 0;
}

輸出:

—–ThinkPad—–
CPU : i5 - 6200U
Mainboard : Intel DH57DD
Ram : DDR4
VideoCard : NVIDIA Geforce 920MX
—–Yoga—–
CPU : i7 - 7500U
Mainboard : Intel DP55KG
Ram : DDR5
VideoCard : NVIDIA GeForce 940MX

如果需要建立更多的產品,只需要一個 ConcreteBuilder 即可,並且所有的程式碼都基本相同,客戶端還可以使用此模式輕鬆地建立複雜的產品。

 

五、優缺點

優點:

1、建造者獨立,易擴充套件。

2、便於控制細節風險。

缺點:

1、產品必須有共同點,範圍有限制。

2、如內部變化複雜,會有很多的建造類。