首页 > 编程笔记 > C++笔记 阅读:9

建造者模式详解(附带C++实例)

建造者模式是一种用于构建复杂对象的设计模式,它非常适合用于管理具有多个组件和复杂构建过程的对象。

下面通过一个案例来探讨建造者模式在实际应用中的价值和效用。

设想你正在开发一个文档编辑软件,这个软件的一个关键功能是生成包含多种元素(如文本、图像、表格)的复杂报告。这些报告不仅内容丰富,而且需要支持多种输出格式,包括 PDF、HTML 和 Word。每种元素和每种格式的创建步骤都可能不同,直接在主代码中管理这些步骤将使代码复杂且难以维护。

那么就出现了以下几个问题:

建造者模式的应用

建造者模式主要用于分离复杂对象的构造过程和表示方式,以增加代码的灵活性和可维护性。它通过提供一个逐步构造复杂对象的接口,允许不同的表示方式和精确的控制构造过程,同时隐藏对象的内部结构和组装细节。

建造者模式特别适合构建需要多个部分和步骤的复杂对象,使得构造过程更加模块化,易于应对未来的变化或扩展。

因此,建造者模式可以通过将一个复杂对象的构造过程分解为多个简单的步骤,并允许按照不同的方法和顺序来构建对象,以解决上述问题。

那么这个模式又是如何实现的呢:

建造者模式的代码示例

// 声明一个DocumentBuilder抽象基类,定义构建文档的各个步骤
class DocumentBuilder {
public:
    // 构建文档的头部,具体实现由子类提供
    virtual void buildHeader() = 0;
    // 构建文档的文本部分,具体实现由子类提供
    virtual void buildTextSection() = 0;
    // 构建文档的图像部分,具体实现由子类提供
    virtual void buildImageSection() = 0;
    // 构建文档的脚部,具体实现由子类提供
    virtual void buildFooter() = 0;
    // 获取构建完成的文档对象,返回类型为Document指针
    virtual Document* getResult() = 0;
};
// 实现一个具体建造者HTMLDocumentBuilder,用于构建HTML格式的文档
class HTMLDocumentBuilder : public DocumentBuilder {
    // 私有成员,指向正在构建的HTML文档对象
    HTMLDocument* doc;
public:
    // 构造函数,创建一个新的HTMLDocument对象
    HTMLDocumentBuilder() { doc = new HTMLDocument(); }
    // 实现基类定义的构建文档头部的方法
    void buildHeader() override { doc->addHeader("<html><body>"); }
    // 实现基类定义的构建文本部分的方法
    void buildTextSection() override { doc->addTextSection("<p>Some text</p>"); }
    // 实现基类定义的构建图像部分的方法
    void buildImageSection() override { doc->addImageSection("<img
src='image.jpg'/>"); }
    // 实现基类定义的构建脚部的方法
    void buildFooter() override { doc->addFooter("</body></html>"); }
    // 实现基类定义的获取构建结果的方法,返回构建完成的HTML文档
    Document* getResult() override { return doc; }
};
// 类似地,可以定义 PDFDocumentBuilder和WordDocumentBuilder
// 这些类将实现相同的DocumentBuilder接口,但具体的构建细节会根据文档类型(PDF、Word)而有所不同
在这个代码示例中,DocumentBuilder 是一个抽象类,它定义了所有文档构建者共有的接口。这些接口包括构建文档的头部、文本部分、图像部分和脚部的方法,以及一个获取构建结果的方法。

HTMLDocumentBuilder 是 DocumentBuilder 接口的一个具体实现,它封装了构建 HTML 文档的具体步骤,并在内部持有一个正在被构建的文档对象。这样的设计允许将文档的构建过程与具体的文档类型解耦,使得在添加新的文档类型(如 PDF 或 Word)时,只需增加新的构建者类而不需要修改其他代码。这正是建造者模式的核心价值所在。

可以发现,工厂模式和建造者模式都提供了创建对象的方式,同时都实现了客户端代码与对象创建过程的解耦。不过,这两个模式的应用场景和目的有所不同,这也是它们各自存在的原因。

我们可以通过一些常见的场景和需求来指导这个选择:

1) 建造者模式在以下情况下是合适的:
2) 工厂模式通常在以下情况下是合适的:
虽然没有明确的界限说明何时应该切换使用这两种模式,但有一些通用做法:
在实际应用中,还可能会遇到需要结合使用这两种模式的情况。例如,一个复杂对象的构建可能使用建造者模式,而这些复杂对象的不同实现则通过工厂模式来创建。这种混合使用可以提供更大的灵活性和可扩展性。

在实践中,项目的具体需求和未来可能的扩展,通常是设计决策中的重要考虑因素。

相关文章