前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式 - 生成器

设计模式 - 生成器

作者头像
开源519
发布2021-11-02 14:45:25
2790
发布2021-11-02 14:45:25
举报
文章被收录于专栏:开源519开源519

生成器模式

生成器模式属于创建型设计模式,根据需要分步创建功能较多的对象。

场景

问题

假设要生产两款不同品牌的笔记本ThinkPad X 13和MateBook X Pro,笔记本的参数包括重量、内存、硬盘和CPU,且同一型号的笔记本参数会存在差异。满足开闭原则的基础下,设计此场景。

分析

此场景主要的对象为两款笔记本,其中内部包含各种参数。因此要构建具体的实例,需要初始化时,对内部成员一一进行初始化。这些初始化代码一般会放在构造函数中,更糟糕的是可能会散落在各种使用代码中,不易被察觉。传统的方法或许暂时可以满足需求,但是维护起来令人抓狂,且违背开闭原则。

概念

此时可引进生成器模式,满足以上的设计需求。为避免在客户端使用时凌乱的使用构造函数,可将笔记本封装成类,内部提供必备参数的设置接口。提供统一的生成接口供用户使用以创建需要的实例。

此处主要涉及到以下几个概念:

生成器

笔记本已经抽象为类了,只需要在使用时创建笔记本实例。但是这些代码放在散乱的主逻辑中是糟糕且难以维护的。因此可实现一个生成器专门用于做此类工作,其功能主要为设置固定的笔记本参数,返回该实例。

不同的笔记本参数肯定是不同的,为符合开闭原则,设计为一类笔记本对应一个生成器实例。因此将生成器抽象为基类,派生出各个具体的生成器子类。

指挥

为便于生成器更加灵活的使用,例如各个参数的设置顺序、某些参数不需要等。可设计一个实例用于指挥生成器的使用。

实现

类图

根据以上分析各类之间的关系,绘制出以下类图。

生成器类图

使用方法

  • 增加新产品笔记本 若为同型号不同配置(低/中/高配)笔记本,可在Cdirector::BuildComputer()中做逻辑,见源码BuildComputer(ENOTEBOOK_TYPE notebookType) 。 若非同型号笔记本,则需CComputer派生出新笔记本的生成类,交由CDirector实例生成具体的笔记本实例。
  • 删除不使用的新产品实例 只需屏蔽CDirector的调用即可。

源码

代码语言:javascript
复制
#include <string>
#include <iostream>

using namespace std;

typedef enum {
    ALLOCATION_MIN = 0,
    ALLOCATION_NORMAL,
    ALLOCATION_HIGH,
    ALLOCATION_MAX
} ENOTEBOOK_TYPE;

class CComputer
{
public:
    void   SetName(string value) { mName = value; }
    string   GetName() { return mName; }
    void   SetWeight(string value) { mWeight = value; }
    string GetWeight() { return mWeight; }
    void   SetMemary(string value) { mMemary = value; }
    string GetMemary() { return mMemary; }
    void   SetHardDisk(string value) { mHardDisk = value; }
    string GetHardDisk() { return mHardDisk; }
    void   SetCpu(string value) { mCpu = value; }
    string GetCpu() { return mCpu; }

private:
    string mName;
    string mWeight;
    string mMemary;
    string mHardDisk;
    string mCpu;
};

class CComputerBuilder
{
public:

    virtual void BuildName() = 0;
    virtual void BuildWeight() = 0;
    virtual void BuildMemary() = 0;
    virtual void BuildHardisk() = 0;
    virtual void BuildHardiskHigh() = 0;
    virtual void BuildCpu() = 0;
    virtual CComputer* GetComputer() = 0;
};

class CThinkPadX13Builder : public CComputerBuilder
{
public:

    CThinkPadX13Builder()
    {
        mThinkPadX13 = new CComputer();
    }

    ~CThinkPadX13Builder()
    {
        delete mThinkPadX13;
    }

    void BuildName()
    {
        mThinkPadX13->SetName("ThinkPad X13");
    }

    void BuildWeight()
    {
        mThinkPadX13->SetWeight("1.3Kg");
    }

    void BuildMemary()
    {
        mThinkPadX13->SetMemary("32GB");
    }

    void BuildHardisk()
    {
        mThinkPadX13->SetHardDisk("512G");
    }

    void BuildHardiskHigh()
    {
        mThinkPadX13->SetHardDisk("1TB");
    }

    void BuildCpu()
    {
        mThinkPadX13->SetCpu("I5-10210U");
    }

    CComputer *GetComputer() {return mThinkPadX13;}

private:
    CComputer* mThinkPadX13;
};

class CMateBookXProBuilder : public CComputerBuilder
{
public:
    CMateBookXProBuilder()
    {
        mMateBookXPro = new CComputer();
    }

    ~ CMateBookXProBuilder()
    {
        delete mMateBookXPro;
    }

    void BuildName()
    {
        mMateBookXPro->SetName("MateBook X Pro");
    }

    void BuildWeight()
    {
        mMateBookXPro->SetWeight("1.33KG");
    }

    void BuildMemary()
    {
        mMateBookXPro->SetMemary("16G");
    }

    void BuildHardisk()
    {
        mMateBookXPro->SetHardDisk("1TB");
    }

    void BuildHardiskHigh()
    {
        mMateBookXPro->SetHardDisk("2TB");
    }

    void BuildCpu()
    {
        mMateBookXPro->SetCpu("i7-1165G7");
    }

    CComputer* GetComputer() { return mMateBookXPro; }

private:
    CComputer* mMateBookXPro;
};

class CDirector
{
public:
    CDirector(CComputerBuilder *pBuilder)
    {
        mBuilder = pBuilder;
    }

    void BuildComputer(ENOTEBOOK_TYPE notebookType)
    {
        mBuilder->BuildName();
        mBuilder->BuildWeight();
        mBuilder->BuildMemary();
        mBuilder->BuildCpu();

        if (notebookType == ALLOCATION_NORMAL)
        {
            mBuilder->BuildHardisk();
        } else if (notebookType == ALLOCATION_HIGH) {
            mBuilder->BuildHardiskHigh();
        } else {
            cout << "Error: No this type!" << endl;
        }

    }

private:
    CComputerBuilder* mBuilder;
};

static void show_params(CComputer *pComputer)
{
    cout << "---" << pComputer->GetName() << "---" << endl;
    cout << "Weight: " << pComputer->GetWeight() << endl;
    cout << "Memary: " << pComputer->GetMemary() << endl;
    cout << "Hard disk: " << pComputer->GetHardDisk() << endl;
    cout << "Cpu: " << pComputer->GetCpu() << endl;
    cout << endl;
}

int main(int argc, char *argv[])
{
    CThinkPadX13Builder *theComputerBuilder1 = new CThinkPadX13Builder();
    CDirector *theDirector1 = new CDirector(theComputerBuilder1);
    theDirector1->BuildComputer(ALLOCATION_HIGH);
    CComputer *theComputer1 =  theComputerBuilder1->GetComputer();
    show_params(theComputer1);
    delete theDirector1;
    delete theComputerBuilder1;

    CMateBookXProBuilder *theComputerBuilder2 = new CMateBookXProBuilder();
    CDirector *theDirector2 = new CDirector(theComputerBuilder2);
    theDirector2->BuildComputer(ALLOCATION_HIGH);
    CComputer *theComputer2 =  theComputerBuilder2->GetComputer();
    show_params(theComputer2);
    delete theDirector2;
    delete theComputerBuilder2;

    return 0;
}

输出

代码语言:javascript
复制
---ThinkPad X13---
Weight: 1.3Kg
Memary: 32GB
Hard disk: 1TB
Cpu: I5-10210U

---MateBook X Pro---
Weight: 1.33KG
Memary: 16G
Hard disk: 2TB
Cpu: i7-1165G7

总结

在软件设计时,主函数的代码尽量减少实例初始化的动作,将初始化的行为尽量封装起来供主函数调用。主函数大多为业务逻辑,过多的代码会影响美观及维护。

推荐文章

C++设计模式 - 工厂模式

C++常用设计模式

(refactoringguru.cn/design-patterns/cpp)

最后

用心感悟,认真记录,写好每一篇文章,分享每一框干货。

更多文章内容包括但不限于C/C++、Linux、开发常用神器等,可进入开源519公众号聊天界面回复“文章目录” 或者 菜单栏选择“文章目录”查看。源码获取,聊天输入本文章标题。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源519 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 生成器模式
  • 场景
  • 概念
  • 实现
  • 总结
    • 推荐文章
      • 最后
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档