2018-09-18 22:19:07
依赖倒转原则
高层模块不依赖低层模块,二者都不依赖细节。抽象不应该依赖细节,细节应该依赖于抽象。这句话什么意思呢,就是说你有一个虚基类(抽象),这个基类每一个方法都有明确的含义,稳定的传参形式和返回类型。不管子类如何实现这些方法(细节),只要完成了基类要求的功能即可。
建造者模式
如果,你需要将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示时,此时就需要建造者模式(Builder)又叫做生成器模式。建造者模式可以将一个产品内部表象与产品的生成过程分隔开来,从而可以使一个建造过程具有不同的内部表象的产品对象。如果我们用了建造者模式,那么用户就只需要指定需要建造的类型就可以得到它们,而具体的建造过程和细节就不需要知道了。
建造者(Builder)模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
使用建造者流程:1.抽象出一个稳定的建造流程(就是一个包含一些列方法的虚基类咯);
2.当需要构建一个符合这个建造流程的对象时,我们只需要从虚基类中派生出一个子类,子类按照自己的特殊要求去实现基类的方法即可。
3.构建指挥者(Director)类,这在建造者模式中是非常重要的一个类,用它来控制建造流程,也用它来隔离用户与建造过程的关联。实际上就是根据用户的选择来建造他需要的类。而建造的过程是用户不需要关心的。
建造者UML图
其中:Builder是一个创建产品的流程提供者(虚基类),它指定了创建一个Product对象的各个部件的抽象接口。
ConcreteBuilder是具体建造者,实现Builder接口,构造和装配各个部件。Product就是具体的产品角色了。
Director是构建一个使用Builder接口的对象。
建造者模式的使用场景:主要用于创建一些复杂的对象,这些对象内部构建间的顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。使用建造者模式的好处是,使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
代码实现
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; } }
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
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"); }
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); }
根据上面的示例代码,如果我们想构建新的Product的实例,那么只需要新增一个具体建造者(Concrete Bulider),并将其添加到客户代码的调用中即可。