零前缀
hello,你好,欢迎来到《自由技艺》的C系列特辑。
先声明下:今天的题目有点』标题党『之嫌哈,最近手头有个重构 C++ 代码的项目,对于如何保证其扩展性,最大程度方便开发者进行二次开发,始终没有好的思路,于是想到了设计模式中的建造者模式,现分享给大家吧,但是感觉还是有点鸡肋,不够好,也欢迎各位大神指导一二,不甚感激。1 什么是建造者模式?
先看下类图吧:
什么意思呢?举个例子:假如我们要造车,车有好多种型号,现有的流水线去如何去适应未来可能的新车型呢
首先,我们假设造车有几项固定的流程:比如先造发动机(producePartA),然后造车壳(producePartB),再造轮胎(producePartC),最后再安个行车记录仪或者倒车摄像头啥的。
接下来,我们就开始造车了,比如要造两款新车(Product1 和 Product2),那么我们就需要对应的建造者类(ConcreteBuilder1 和 ConcreteBuilder2)就行。
建造者模式看起来扩展性很好,但是有个致命问题,就是造车的流程必须固定,如果某款车型需要在流程 A 和 流程 B 之间需要额外加一步,比如流程 A2,那就不好办了,只能把这步流程融合在 A 里或者 B 里,但是呢?如果没有建造者模式,我们只能采用以下两种方式:
- 最简单的方法是扩展造车基类, 然后创建一系列涵盖所有参数组合的子类。 但最终你将面对相当数量的子类。 任何新增的参数都会让这个层次结构更加复杂。
2. 另一种方法则无需生成子类。 你可以在造车基类中创建一个包括所有可能参数的超级构造函数, 并用它来控制车对象。 这种方法确实可以避免生成子类, 但它却会造成另外一个问题。拥有大量输入参数的构造函数也有缺陷: 这些参数也不是每次都要全部用上的。通常情况下, 绝大部分的参数都没有使用, 这使得对于构造函数的调用十分不简洁。
2 建造者模式 C++ 代码
#include <iostream>
#include <cstring>
#include <stdexcept>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <mutex>
#include <deque>
#include <thread>
#include <;
#include <uni;
#include <memory>
#include <condition_variable>
#include <future>
#include <list>
class Product1 {
public:
std::string parts;
void listParts() {
std::cout << "create products: " << parts << "\n";
}
};
class Builder {
public:
virtual void producePartA() = 0;
virtual void producePartB() = 0;
virtual void producePartC() = 0;
};
class ConcreteBuilder1 : public Builder {
private:
Product1* product = nullptr;
public:
ConcreteBuilder1() {
product = new Product1();
};
void reset() {
product = new Product1();
};
void producePartA() {
this->product->parts += "PartA1";
}
void producePartB() {
this->product->parts += "PartB1";
}
void producePartC() {
this->product->parts += "PartC1";
}
Product1* getProduct() {
auto result = this->product;
reset();
return result;
}
};
class Director {
private:
Builder* builder = nullptr;
public:
void setBuilder(Builder& builder) {
this->builder = &builder;
}
void buildStdProduct() {
builder->producePartA();
}
void buildAdvanceProduct() {
builder->producePartA();
builder->producePartB();
builder->producePartC();
}
};
int main()
{
Director director;
ConcreteBuilder1 builder;
direc(builder);
direc();
builder.getProduct()->listParts();
direc();
builder.getProduct()->listParts();
return 0;
}
程序输出: