設計模式之建造者模式

2018-09-18 22:19:07

依賴倒轉原則

  高層模塊不依賴低層模塊,兩者都不依賴細節。抽象不該該依賴細節,細節應該依賴於抽象。這句話什麼意思呢,就是說你有一個虛基類(抽象),這個基類每個方法都有明確的含義,穩定的傳參形式和返回類型。無論子類如何實現這些方法(細節),只要完成了基類要求的功能便可。ios

建造者模式

  若是,你須要將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示時,此時就須要建造者模式(Builder)又叫作生成器模式。建造者模式能夠將一個產品內部表象與產品的生成過程分隔開來,從而可使一個建造過程具備不一樣的內部表象的產品對象。若是咱們用了建造者模式,那麼用戶就只須要指定須要建造的類型就能夠獲得它們,而具體的建造過程和細節就不須要知道了。ide

  建造者(Builder)模式:將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。函數

  使用建造者流程:1.抽象出一個穩定的建造流程(就是一個包含一些列方法的虛基類咯);ui

          2.當須要構建一個符合這個建造流程的對象時,咱們只須要從虛基類中派生出一個子類,子類按照本身的特殊要求去實現基類的方法便可。spa

          3.構建指揮者(Director)類,這在建造者模式中是很是重要的一個類,用它來控制建造流程,也用它來隔離用戶與建造過程的關聯。實際上就是根據用戶的選擇來建造他須要的類。而建造的過程是用戶不須要關心的。code

建造者UML圖

  其中:Builder是一個建立產品的流程提供者(虛基類),它指定了建立一個Product對象的各個部件的抽象接口。對象

     ConcreteBuilder是具體建造者,實現Builder接口,構造和裝配各個部件。Product就是具體的產品角色了。blog

     Director是構建一個使用Builder接口的對象。接口

  建造者模式的使用場景:主要用於建立一些複雜的對象,這些對象內部構建間的順序一般是穩定的,但對象內部的構建一般面臨着複雜的變化。使用建造者模式的好處是,使得建造代碼與表示代碼分離,因爲建造者隱藏了該產品是如何組裝的,因此若須要改變一個產品的內部表示,只須要再定義一個具體的建造者就能夠了。get

代碼實現

1.要構建的類:

#ifndef PRODUCT_H_
#define PRODUCT_H_
#include <vector>
#include <string>
#include <iostream>
class Product
{
public:
    void addPart(const std::string strPart);
    void show();
    Product() = default;
    ~Product() = default;
private:
    std::vector<std::string> m_vecPart;
};
#endif

#include "Product.h"

void Product::addPart(const std::string strPart)
{
    m_vecPart.push_back(strPart);
}

void Product::show()
{
   for(auto value : m_vecPart)
   {
    std::cout << value << std::endl;
   }
}
Product

2.抽象建造者(Builder)

#ifndef BUILDER_H_
#define BUILDER_H_
#include <string>
class Builder
{
public:
    virtual void buildPartA(const std::string strPartA) = 0;
    virtual void buildPartB(const std::string strPartB) = 0;
    virtual void buildPartC(const std::string strPartC) = 0;
    virtual void buildPartD(const std::string strPartD) = 0;
    virtual void getResult() = 0;
    Builder() = default;
    virtual ~Builder() = default;
};
#endif
Builder

3.具體建造者(Concrete Builder)

#ifndef CONCRETEBUILDER1_H_
#define CONCRETEBUILDER1_H_
#include "Builder.h"
#include "Product.h"
class ConcreteBuilder1:public Builder
{
public:
    void buildPartA(const std::string strPartA) override;
    void buildPartB(const std::string strPartB) override;
    void buildPartC(const std::string strPartC) override;
    void buildPartD(const std::string strPartD) override;
    void getResult() override;
    ConcreteBuilder1() = default;
    ~ConcreteBuilder1() = default;
private:
    Product m_myProduct;
};
#endif

#include "ConcreteBuilder1.h"

void ConcreteBuilder1::buildPartA(const std::string strPartA)
{
    m_myProduct.addPart(strPartA);
}

void ConcreteBuilder1::buildPartB(const std::string strPartB)
{
    m_myProduct.addPart(strPartB);
}

void ConcreteBuilder1::buildPartC(const std::string strPartC)
{
    m_myProduct.addPart(strPartC);
}

void ConcreteBuilder1::buildPartD(const std::string strPartD)
{
    m_myProduct.addPart(strPartD);
}

void ConcreteBuilder1::getResult() 
{
    m_myProduct.show();
}

4.建造的指揮者(Director)也是建造者模式的核心類

#ifndef DIRECTOR_H_
#define DIRECTOR_H_
#include "Builder.h"
class Director
{
public:
    void construct(Builder* builder);
    Director() = default;
    ~Director() = default;
};
#endif 

#include "Director.h"
void Director::construct(Builder* builder)
{
    builder->buildPartA("This is a C++ Program!");
    builder->buildPartB("This is a Builder Model");
    builder->buildPartC("Hello ");
    builder->buildPartD("Could you understand");
}
Director

5.main函數

#include "Director.h"
#include "Builder.h"
#include "ConcreteBuilder1.h"

using namespace std;

int main(int argc,char *argv[])
{
    Director myDirector;
    Builder *myBuilder = new ConcreteBuilder1;
    myDirector.construct(myBuilder);
    myBuilder->getResult();
    if(nullptr != myBuilder)
    {
    delete myBuilder;
        myBuilder=nullptr;
    }
    return(1);
}
main

  根據上面的示例代碼,若是咱們想構建新的Product的實例,那麼只須要新增一個具體建造者(Concrete Bulider),並將其添加到客戶代碼的調用中便可。

相關文章
相關標籤/搜索