IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> [大话设计模式C++版] 第13章 好菜每回味不同 —— 建造者模式 -> 正文阅读

[C++知识库][大话设计模式C++版] 第13章 好菜每回味不同 —— 建造者模式

源码可以在这里找到 大话设计模式C++版

建造小人一

实现画小人的程序

//Widget.cpp
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    createThin(painter);
    createFat(painter, 200);
}

void Widget::createThin(QPainter &painter, int x, int y)
{
    painter.drawEllipse(QRect(50+x, 20+y, 30, 30));
    painter.drawRect(60+x, 50+y, 10, 50);
    painter.drawLine(60+x, 50+y, 40+x, 100+y);
    painter.drawLine(70+x, 50+y, 90+x, 100+y);
    painter.drawLine(60+x, 100+y, 45+x, 150+y);
    painter.drawLine(70+x, 100+y, 85+x, 150+y);
}

void Widget::createFat(QPainter &painter, int x, int y)
{
    painter.drawEllipse(QRect(50+x, 20+y, 30, 30));
    painter.drawEllipse(QRect(45+x, 50+y, 40, 50));
    painter.drawLine(50+x, 50+y, 30+x, 100+y);
    painter.drawLine(80+x, 50+y, 100+x, 100+y);
    painter.drawLine(60+x, 100+y, 45+x, 150+y);
    painter.drawLine(70+x, 100+y, 85+x, 150+y);
}

建造小人二

创建两个类,不管谁都可以调用它们

#include <QPainter>

class PersonThinBuilder
{
public:
    PersonThinBuilder(QPainter* painter) {
        m_painter = painter;
    }
    void Build(int x=0, int y=0) {
        m_painter->drawEllipse(QRect(50+x, 20+y, 30, 30));
        m_painter->drawRect(60+x, 50+y, 10, 50);
        m_painter->drawLine(60+x, 50+y, 40+x, 100+y);
        m_painter->drawLine(70+x, 50+y, 90+x, 100+y);
        m_painter->drawLine(60+x, 100+y, 45+x, 150+y);
        m_painter->drawLine(70+x, 100+y, 85+x, 150+y);
    }

private:
    QPainter* m_painter;
};

胖小人类,类似受小人类。

//widget.cpp 客户端代码
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    PersonThinBuilder personThin(&painter);
    PersonFatBuilder personFat(&painter);
    personThin.Build();
    personFat.Build(150);
}

建造者模式

在这里插入图片描述

先抽象一个画小人的基类 PersonBuilder类

//PersonBuilder.h
class PersonBuilder
{
public:
    PersonBuilder(QPainter* painter, int x, int y) {
        m_painter = painter;
        m_x = x;
        m_y = y;
    }
    virtual void BuildHead() = 0;
    virtual void BuildBody() = 0;
    virtual void BuildArmLeft() = 0;
    virtual void BuildArmRight() = 0;
    virtual void BuildLegLeft() = 0;
    virtual void BuildLegRight() = 0;

protected:
    QPainter* m_painter;
    int m_x;
    int m_y;
};

具体小人类继承 PersonBuilder类

class PersonThinBuilder : public PersonBuilder
{
public:
    PersonThinBuilder(QPainter* painter, int x=0, int y=0) : PersonBuilder(painter, x, y) {}
    virtual void BuildHead() {
        m_painter->drawEllipse(QRect(50+m_x, 20+m_y, 30, 30));
    }
    virtual void BuildBody() {
        m_painter->drawRect(60+m_x, 50+m_y, 10, 50);
    }
    virtual void BuildArmLeft() {
        m_painter->drawLine(60+m_x, 50+m_y, 40+m_x, 100+m_y);
    }
    virtual void BuildArmRight() {
        m_painter->drawLine(70+m_x, 50+m_y, 90+m_x, 100+m_y);
    }
    virtual void BuildLegLeft() {
        m_painter->drawLine(60+m_x, 100+m_y, 45+m_x, 150+m_y);
    }
    virtual void BuildLegRight() {
        m_painter->drawLine(70+m_x, 100+m_y, 85+m_x, 150+m_y);
    }
};

还需要一个指挥画小人的类 PersonDirector类

//PersonDirector.h
class PersonDirector
{
private:
    std::shared_ptr<PersonBuilder> m_pb;
public:
    PersonDirector(std::shared_ptr<PersonBuilder> pb) : m_pb(pb) {}
    void CreatePerson() {
        m_pb->BuildHead();
        m_pb->BuildBody();
        m_pb->BuildArmLeft();
        m_pb->BuildArmRight();
        m_pb->BuildLegLeft();
        m_pb->BuildLegRight();
    }
};

客户端代码

//widget.cpp
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    auto ptb = std::shared_ptr<PersonThinBuilder>(new PersonThinBuilder(&painter));
    auto pdThin = std::shared_ptr<PersonDirector>(new PersonDirector(ptb));
    pdThin->CreatePerson();

    auto pfb = std::shared_ptr<PersonFatBuilder>(new PersonFatBuilder(&painter, 100));
    auto pdFat = std::shared_ptr<PersonDirector>(new PersonDirector(pfb));
    pdFat->CreatePerson();
}

Builder构建器模式 [李建忠C++笔记]

“对象创建”模式

  • 通过“对象创建”模式绕开new,来避免对像创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
  • 典型模式
    • Factory Method
    • Abstract Factory
    • Prototype
    • Builder

动机(Motivation)

  • 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
  • 如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变。
class House {};

class HouseBuilder {
public:
    House* GetResult() {
        return pHouse;
    }
    virtual ~HouseBuilder() {}
public:
    House* pHouse;
    virtual void BuildPart1() = 0;
    virtual void BuildPart2() = 0;
    virtual bool BuildPart3() = 0;
    virtual void BuildPart4() = 0;
    virtual void BuildPart5() = 0;
};

class StoneHouse : public House {};

class StoneHouseBuilder : public HouseBuilder {
public:
    virtual void BuildPart1() {
        //pHouse->...
    }
    virtual void BuildPart2() {

    }
    virtual bool BuildPart3() {

    }
    virtual void BuildPart4() {
        
    }
    virtual void BuildPart5() {

    }
};

class HouseDirector {
public:
    HouseBuilder* pHouseBuilder;
    HouseDirector(HouseBuilder* pHouseBuilder) {
        this->pHouseBuilder = pHouseBuilder;
    }
    House* Construct() {
        pHouseBuilder->BuildPart1();

        for (int i = 0; i < 4; i++) {
            pHouseBuilder->BuildPart2();
        }

        bool flag = pHouseBuilder->BuildPart3();

        if (flag) {
            pHouseBuilder->BuildPart4();
        }

        pHouseBuilder->BuildPart5();

        return pHouseBuilder->GetResult();
    }
};

int main()
{
    StoneHouseBuilder* stoneHouseBuilder = new StoneHouseBuilder();
    HouseDirector* pHouseDirector = new HouseDirector(stoneHouseBuilder);
    pHouseDirector->Construct();
}

在这里插入图片描述

要点总结

  • Builder模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
  • 变化点在哪里,封装哪里——Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
  • 在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++ vs. C#)
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:13:43  更:2022-10-17 12:17:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 4:38:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码