网站后台卸载cmsdede,自己做网站页面,可以做企业宣传的网站,淮北矿业工程建设有限公司网站目录
1.简介
2.结构
3.使用场景
4.实例
5.优缺点
6.与其他模式的关系
7.总结 1.简介 生成器模式#xff08;Builder Pattern#xff09;是一种创建型设计模式#xff0c;它允许你通过一步一步构建复杂对象#xff0c;而不是通过一个包含大量参数的构造函数或方法。该…目录
1.简介
2.结构
3.使用场景
4.实例
5.优缺点
6.与其他模式的关系
7.总结 1.简介 生成器模式Builder Pattern是一种创建型设计模式它允许你通过一步一步构建复杂对象而不是通过一个包含大量参数的构造函数或方法。该模式特别适用于需要生成的对象具有多个可选属性且这些属性的组合会导致大量构造函数重载的情况。 生成器模式通过将对象的构建过程分解成多个步骤使得每一步都可以单独配置。这样不仅提高了代码的可读性和可维护性还使得构建过程更加灵活和可扩展。 与其他创建型模式不同的是生成器模式允许你在一个过程中创建一个对象而无需等待所有部分都准备好。这种模式特别适用于需要构造不同表示或状态的复杂对象时。
2.结构 生成器模式的UML结构图如下所示 1) 生成器Builder接口声明在所有类型生成器中通用的产品构造步骤。 2) 具体生成器Concrete Builders提供构造过程的不同实现。具体生成器也可以构造不遵循通用接口的产品。 3) 产品Products是最终生成的对象。由不同生成器构造的产品无需属于同一类层次结构或接口。 4) 主管Director类定义调用构造步骤的顺序这样你就可以创建和复用特定的产品配置。 5) 客户端Client必须将某个生成器对象与主管类关联。一般情况下你只需通过主管类构造函数的参数进行一次性关联即可。此后主管类就能使用生成器对象完成后续所有的构造任务。但在客户端将生成器对象传递给主管类制造方法时还有另一种方式。在这种情况下你在使用主管类生产产品时每次都可以使用不同的生成器。
3.使用场景
1使用生成器模式可避免“重叠构造函数telescopicconstructor”的出现。 假设你的构造函数中有十个可选参数那么调用该函数会非常不方便因此你需要重载这个构造函数新建几个只有较少参数的简化版。但这些构造函数仍需调用主构造函数传递一些默认数值来替代省略掉的参数。生成器模式让你可以分步骤生成对象而且允许你仅使用必须的步骤。应用该模式后你再也不需要将几十个参数塞进构造函数里了。
2当你希望使用代码创建不同形式的产品例如石头或木头房屋时可使用生成器模式。 如果你需要创建的各种形式的产品它们的制造过程相似且仅有细节上的差异此时可使用生成器模式。基本生成器接口中定义了所有可能的制造步骤具体生成器将实现这些步骤来制造特定形式的产品。同时主管类将负责管理制造步骤的顺序。
3使用生成器构造组合树或其他复杂对象。 当一个对象的构建过程非常复杂涉及多个步骤和多个部件时使用生成器模式可以将对象的构建过程与其表示分离使得同样的构建过程可以创建不同的表示。 例如构建一个汽车对象可能涉及设置车身、引擎、车轮和内饰等多个部件每个部件都有多种选择。使用生成器模式可以逐步构建汽车对象并根据需要选择不同的部件。
4.实例
下面我将展示一个稍微复杂一些的应用场景即构建一个包含多个可选组件的计算机配置对象。
首先我们定义一个Computer类它代表我们要构建的计算机对象
#include iostream
#include string
#include vector
#include memoryclass Computer {
private:std::string caseType;std::string cpu;std::string gpu;std::string ram;std::string storage;std::vectorstd::string peripherals;// 禁止直接实例化Computer(const std::string caseType, const std::string cpu, const std::string gpu,const std::string ram, const std::string storage,const std::vectorstd::string peripherals): caseType(caseType), cpu(cpu), gpu(gpu), ram(ram), storage(storage), peripherals(peripherals) {}friend class ComputerBuilder;public:void display() const {std::cout Case Type: caseType \n;std::cout CPU: cpu \n;std::cout GPU: gpu \n;std::cout RAM: ram \n;std::cout Storage: storage \n;std::cout Peripherals: ;for (const auto peripheral : peripherals) {std::cout peripheral ;}std::cout \n;}
};
接下来我们定义一个ComputerBuilder类用于逐步构建Computer对象
class ComputerBuilder {
protected:std::string caseType;std::string cpu;std::string gpu;std::string ram;std::string storage;std::vectorstd::string peripherals;public:virtual ~ComputerBuilder() default;ComputerBuilder setCaseType(const std::string caseType) {this-caseType caseType;return *this;}ComputerBuilder setCpu(const std::string cpu) {this-cpu cpu;return *this;}ComputerBuilder setGpu(const std::string gpu) {this-gpu gpu;return *this;}ComputerBuilder setRam(const std::string ram) {this-ram ram;return *this;}ComputerBuilder setStorage(const std::string storage) {this-storage storage;return *this;}ComputerBuilder addPeripheral(const std::string peripheral) {peripherals.push_back(peripheral);return *this;}virtual Computer build() const 0;
};
注意这里我们将ComputerBuilder定义为一个抽象类并声明了一个纯虚函数build这样我们就可以有不同的具体实现来构建不同类型的计算机。
现在我们定义一个具体的GamingComputerBuilder类来构建游戏计算机
class GamingComputerBuilder : public ComputerBuilder {
public:GamingComputerBuilder() {// 可以设置一些默认配置setCaseType(ATX Mid Tower);setCpu(Intel i9);// ... 其他默认配置}Computer build() const override {return Computer(caseType, cpu, gpu, ram, storage, peripherals);}
};
在GamingComputerBuilder中我们可以设置一些默认配置或者覆盖父类的方法来提供特定的配置选项。
最后我们定义一个ComputerDirector类可选来管理构建过程并展示如何使用这些类来构建一个计算机对象
class ComputerDirector {
private:ComputerBuilder* builder;public:ComputerDirector(ComputerBuilder* builder) : builder(builder) {}void setBuilder(ComputerBuilder* builder) {this-builder builder;}Computer constructGamingComputer() {builder-setGpu(NVIDIA RTX 3090);builder-setRam(32GB DDR4);builder-setStorage(2TB SSD);builder-addPeripheral(Gaming Keyboard);builder-addPeripheral(Gaming Mouse);// ... 其他配置return builder-build();}
};int main() {GamingComputerBuilder gamingBuilder;ComputerDirector director(gamingBuilder);// 或者使用自定义的构建步骤// gamingBuilder.setCaseType(Custom Case);// ... 其他设置// Computer customComputer gamingBuilder.build();Computer gamingComputer director.constructGamingComputer();gamingComputer.display();return 0;
}
在这个例子中我们展示了如何使用生成器模式来构建一个包含多个可选组件的计算机配置对象。通过定义抽象的ComputerBuilder类和具体的GamingComputerBuilder类我们可以灵活地构建不同类型的计算机并且可以通过ComputerDirector类来管理构建过程尽管在这个例子中ComputerDirector是可选的但在更复杂的场景中它可能会很有用。
5.优缺点
优点
● 你可以分步创建对象暂缓创建步骤或递归运行创建步骤。 ● 生成不同形式的产品时你可以复用相同的制造代码。 ● 单一职责原则。你可以将复杂构造代码从产品的业务逻辑中分离出来。
缺点
由于该模式需要新增多个类因此代码整体复杂程度会有所增加。
6.与其他模式的关系
与工厂模式的关系
工厂模式主要用于生产各种对象这些对象通常是兄弟类继承自同一个基类。兄弟子类通过实现基类接口展现不同的行为并由工厂函数创建。然而工厂模式在创建对象时并不关注构造细节因此在处理复杂对象的生成时可能会显得力不从心。生成器模式同样用于对象的生成但更侧重于构造细节增加了额外的构建流程以便处理复杂对象的构建需求。生成器模式将对象构造的代码从产品类中抽取出来放在一个名为生成器的独立对象中并允许通过不同的生成器来创建不同形式的对象。对比相较于工厂模式生成器模式提供了更灵活和详细的对象构造方式。当对象相对简单时可以使用工厂模式而当对象复杂且需要详细配置时生成器模式则更为适用。
与抽象工厂模式的关系
抽象工厂模式专注于生成一系列相关对象但它在对象构造复杂时其能力也有限。抽象工厂模式通过定义一个接口使得客户端可以创建相关或依赖对象的家族而无需明确指定具体类。生成器模式虽然也用于创建对象但更侧重于对象的逐步构造和细节配置。生成器模式允许开发者通过不同的生成器来创建具有不同配置和形式的对象。联系与区别两者都提供了对象的创建方式但抽象工厂模式更侧重于对象的家族创建而生成器模式则更侧重于对象的逐步构造和细节配置。此外抽象工厂模式通常会立即返回产品而生成器模式则允许在获取产品前执行一些额外的构造步骤。
与其他模式的关系
桥接模式生成器模式可以与桥接模式结合使用其中主管类负责抽象工作而各种不同的生成器负责实现工作。这种结合可以使得对象构造更加灵活和可扩展。原型模式原型模式通过复制现有对象来创建新对象而生成器模式则通过逐步构造来创建对象。虽然两者在对象创建方式上有所不同但在某些情况下它们可以相互补充共同实现复杂的对象创建需求。单例模式抽象工厂、生成器和原型模式都可以用单例来实现以确保对象的唯一性和全局可访问性。然而这种实现方式并不常见因为它可能会增加系统的复杂性和维护成本。
7.总结 生成器模式通过将复杂对象的构建过程与表示分离使得同样的构建过程可以创建不同的表示。它允许逐步构建对象通过调用生成器对象的方法来添加或修改对象的部件。