设计模式-建造者模式

建造者模式

应用场景

​ 当一个类的构造函数参数有多个时,比如超过四个,而且这些参数有些是可选时,我们通常有两种方法来构建它的对象。例如我们现在有一个如下类Computer,其中CPUram是必填参数,而其他3个是可选参数,那么我们如何构造这个类的实例呢,通常有两种常用方式:

c 复制代码
#include <iostream>
#include <string>

class Computer1{
private:
    //必选
    std::string cpu;
    std::string ram;
    
    //可选
    std::string keyboard;
    std::string display;
public:
    Computer1();
    Computer1(std::string cpu,std::string ram){
        Computer1(cpu,ram,"罗技");
    }
    
    Computer1(std::string cpu,std::string ram,std::string keyboard){
        Computer1(cpu,ram,"三星显示器");
    }
    Computer1(std::string cpu,std::string ram,std::string keyboard,std::string display)
        :cpu(cpu),ram(ram),keyboard(keyboard),display(display){}

};

class Computer2{
private:
    //必选
    std::string cpu;
    std::string ram;
    
    //可选
    std::string keyboard;
    std::string display;
public:
    Computer2(std::string cpu,std::string ram):cpu(cpu),ram(ram){}
    void setCpu(std::string name){this->cpu = name;}
    void SetRam(std::string name){this->ram = name;}
    void setKeyboard(std::string name){this->keyboard = name;}
    void setDisplay(std::string name){this->display = name;}
};


 

​ 那么这两种方式有什么弊端呢?

  1. 第一种方式主要是使用及阅读不方便,参数较多,调用者分不清参数的具体含义。同时,参数太多容易混淆
  2. 第二种方式在构建过程中对象的属性状态因为类中的属性是分布设置的,容易发生变化,造成错误

建造者模式的实现要点

  • Computer中创建一个静态的Builder,负责产品Computer对象的创建
  • 创建一个指挥者Director,指挥不同的Builder对象创建不同Computer对象
  • Builder中创建一个public的构造函数,参数为Computer中必填的参数,本例子中的CPUram
  • Builder中创建设置函数,对computer中那些可选的参数进行赋值
  • Builder中创建一个build()方法,在其中构建Computer的实例并返回

建造者模式的实现方式

建造者模式由指挥者、抽象建造者、具体建造者和产品等4个要素构成,其基本结构如下。

指挥者角色(Director) :

  • 构建一个是由Builder接口创建的对象

抽象建造则模式(Builder):

  • 为创建一个Product对象的各个部件指定的抽象接口

具体建造者模式 (ConcreteBuilder):

  • 实现Builder接口,构造和装配多个部件

产品角色(Product):

  • 待生成的具体产品

设计类图

代码实现

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class Product{


private:
        string partA;//必选参数
        string partB;
        string partC;
public:
    Product(std::string partA):partA(partA){}
    //省略get   以及toString方法
    void setPartA(string param){this->partA = param;}
    void setPartB(string param){this->partB = param;}   
    void setPartC(string param){this->partC = param;}      

    void show(){
        cout<<"Product[partA="<<partA<<",partB = "<<partB<<",partC =  "<<partC<<"]";
        
    }
};

//虚基类
class Builder{
    public:
        virtual void        setPartA() = 0;
        virtual void        setPartB() = 0;
        virtual void        setPartC() = 0;
        
        virtual Product*    build() = 0;
};

class ConcreteBuilder: public Builder{
private:
    Product * product;
public: 
    ConcreteBuilder(std::string partA){
        product = new Product(partA);
    }

    void setPartA(){product->setPartA("A");}
    void setPartB(){product->setPartB("B");}
    void setPartC(){product->setPartC("C");}
    Product* build(){return product;}
};

class Director{

private:
    Builder * builder;
public:
    Director(Builder* builder){//传入build子类对象
        this->builder = builder;
    }

    Product* constructA(){
        
        builder->setPartB();
        builder->setPartC();
        return builder->build();
    }

      Product* constructB(){
        builder->setPartA();    
        builder->setPartC();
        return builder->build();
    }
};

void BuildTest(){
    Builder * builder  = new ConcreteBuilder("partA");
    Director* director = new Director(builder);
    
    Product * productA = director->constructA();
    Product * productB = director->constructB();
    
    productA->show(),productB->show();
     
}

int main()
{
    BuildTest();
    return 0;
}

建造者模式的优点

  • 封装性: 是客户端不必知道产品内部组成的细节
  • 建造者独立,易扩展
  • 便于控制细节风险,可以对建造过程逐步细化,而不对其他模块产生任何影响

建造者模式的缺点

  • 增加类数量 : 产生多余的 Builder 对象 ;
  • 内部修改困难 : 如果 产品内部发生变化 , 建造者也要相应修改 ;
相关推荐
AI人工智能+电脑小能手2 小时前
大白话说Java设计模式-34-命令模式(业务实战篇)
java·spring·设计模式·命令模式·异步任务·撤销重做·事务封装
用户202252215063 小时前
字节发布"豆包工作",我从AI PM角度看到的不是功能,是上下文
设计模式
AI人工智能+电脑小能手4 小时前
大白话说Java设计模式-37-中介者模式(源码剖析篇)
java·设计模式·线程池·中介者模式·源码分析·executor·applicationeventmulticaster
thinking_talk6 小时前
换一个 AI IDE,过去的数据还能继续用吗?
ide·ai ide·数据复用
Caster_Z6 小时前
IntelliJ IDEA 安装 Qoder CN (Formerly Lingma)
java·ide·intellij-idea
电子科技圈6 小时前
IAR与东软睿驰达成战略合作,强化软件开发效率与生态协作
设计模式·开源·软件工程·软件构建·代码规范·设计规范·代码复审
吴声子夜歌7 小时前
Java面试——设计模式(四)
java·设计模式·面试
一嘴一个橘子7 小时前
idea 的 双击Shift 全局搜索
java·ide·intellij-idea
nvvas7 小时前
最新版 IntelliJ IDEA 全面介绍:面向现代 Java 开发者的智能 IDE
java·ide·intellij-idea
郭涤生8 小时前
VScode回归ACM模式(古法编程)配置
linux·ide·vscode