news 2026/9/3 4:18:12

建造者模式-创建型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
建造者模式-创建型

一、建造者模式

1.1、核心思想

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。<================>(说人话)创建步骤复杂,需要过多参数,用户只提供自己的参数,只关心最后的结果,不关心中间
的过程。比如diy主机:CPU:是考虑intel还是AMD:i5还是Rzen5 9700x等;内存是ddr5还是ddr4,选择哪个厂家,容量多大,时序多少等。

1.2、为什么需要建造者模式

问题场景

以DIY主机为例:

// 糟糕的设计:伸缩构造函数模式classComputer{public:// 构造函数1:只有必填参数Computer(conststring&cpu,conststring&ram):cpu_(cpu),ram_(ram){}// 构造函数2:加上可选参数Computer(conststring&cpu,conststring&ram,conststring&storage):cpu_(cpu),ram_(ram),storage_(storage){}// 构造函数3:再加上更多可选参数...Computer(conststring&cpu,conststring&ram,conststring&storage,conststring&gpu,conststring&monitor):cpu_(cpu),ram_(ram),storage_(storage),gpu_(gpu),monitor_(monitor){}// 更多构造函数...// 问题:参数太多,难以阅读和维护!private:string cpu_;string ram_;string storage_="";string gpu_="";string monitor_="";boolbluetooth_=false;// ... 更多成员};// 使用:哪个参数对应什么?完全看不懂!Computercomputer("i7","16GB","1TB SSD","RTX 3080","27寸4K",true,false,true);

问题点:

  1. 构造函数的参数太多,难以阅读和维护。
  2. 用户需要记住每个参数的顺序和类型,容易出错。
  3. 扩展性差,每次增加新属性都需要修改构造函数。

建造者模式解决方案

  1. 构建产品类
// 产品类:电脑classComputer{public:// 使用友元类,让Builder可以访问私有成员friendclassComputerBuilder;voidshow()const{std::cout<<"=== 电脑配置 ==="<<std::endl;std::cout<<"CPU: "<<cpu_<<std::endl;std::cout<<"内存: "<<ram_<<std::endl;if(!storage_.empty()){std::cout<<"存储: "<<storage_<<std::endl;}if(!gpu_.empty()){std::cout<<"显卡: "<<gpu_<<std::endl;}if(!monitor_.empty()){std::cout<<"显示器: "<<monitor_<<std::endl;}std::cout<<"蓝牙: "<<(bluetooth_?"支持":"不支持")<<std::endl;std::cout<<"WiFi: "<<(wifi_?"支持":"不支持")<<std::endl;std::cout<<"总价: ¥"<<price_<<std::endl;}private:// 私有构造函数,只能通过Builder创建Computer()=default;// 电脑组件std::string cpu_;std::string ram_;std::string storage_;std::string gpu_;std::string monitor_;boolbluetooth_=false;boolwifi_=false;doubleprice_=0.0;};
  1. 构建建造者类
// 抽象建造者classComputerBuilder{public:virtual~ComputerBuilder()=default;// 构建步骤virtualvoidbuildCPU(conststd::string&cpu)=0;virtualvoidbuildRAM(conststd::string&ram)=0;virtualvoidbuildStorage(conststd::string&storage)=0;virtualvoidbuildGPU(conststd::string&gpu)=0;virtualvoidbuildMonitor(conststd::string&monitor)=0;virtualvoidbuildBluetooth(boolenabled)=0;virtualvoidbuildWifi(boolenabled)=0;// 获取产品virtualstd::unique_ptr<Computer>getResult()=0;};
  1. 构建具体建造者类
// 具体建造者:游戏电脑建造者classGamingComputerBuilder:publicComputerBuilder{private:std::unique_ptr<Computer>computer_;public:GamingComputerBuilder(){computer_=std::make_unique<Computer>();computer_->price_=0.0;// 初始价格}voidbuildCPU(conststd::string&cpu)override{computer_->cpu_=cpu;computer_->price_+=(cpu.find("i9")!=std::string::npos)?3500:2500;std::cout<<"安装CPU: "<<cpu<<std::endl;}voidbuildRAM(conststd::string&ram)override{computer_->ram_=ram;computer_->price_+=(ram.find("32GB")!=std::string::npos)?1200:800;std::cout<<"安装内存: "<<ram<<std::endl;}voidbuildStorage(conststd::string&storage)override{computer_->storage_=storage;computer_->price_+=(storage.find("2TB")!=std::string::npos)?1500:800;std::cout<<"安装存储: "<<storage<<std::endl;}voidbuildGPU(conststd::string&gpu)override{computer_->gpu_=gpu;computer_->price_+=(gpu.find("RTX")!=std::string::npos)?5000:2000;std::cout<<"安装显卡: "<<gpu<<std::endl;}voidbuildMonitor(conststd::string&monitor)override{computer_->monitor_=monitor;computer_->price_+=(monitor.find("4K")!=std::string::npos)?2000:1000;std::cout<<"连接显示器: "<<monitor<<std::endl;}voidbuildBluetooth(boolenabled)override{computer_->bluetooth_=enabled;computer_->price_+=enabled?100:0;std::cout<<"配置蓝牙: "<<(enabled?"支持":"不支持")<<std::endl;}voidbuildWifi(boolenabled)override{computer_->wifi_=enabled;computer_->price_+=enabled?150:0;std::cout<<"配置WiFi: "<<(enabled?"支持":"不支持")<<std::endl;}std::unique_ptr<Computer>getResult()override{std::cout<<"游戏电脑组装完成!"<<std::endl;returnstd::move(computer_);}};// 具体建造者:办公电脑建造者classOfficeComputerBuilder:publicComputerBuilder{private:std::unique_ptr<Computer>computer_;public:OfficeComputerBuilder(){computer_=std::make_unique<Computer>();computer_->price_=0.0;}voidbuildCPU(conststd::string&cpu)override{computer_->cpu_=cpu;computer_->price_+=(cpu.find("i5")!=std::string::npos)?1200:800;std::cout<<"安装CPU: "<<cpu<<std::endl;}voidbuildRAM(conststd::string&ram)override{computer_->ram_=ram;computer_->price_+=400;// 办公电脑内存价格固定std::cout<<"安装内存: "<<ram<<std::endl;}voidbuildStorage(conststd::string&storage)override{computer_->storage_=storage;computer_->price_+=500;std::cout<<"安装存储: "<<storage<<std::endl;}voidbuildGPU(conststd::string&gpu)override{// 办公电脑默认集成显卡if(!gpu.empty()){computer_->gpu_=gpu;computer_->price_+=800;std::cout<<"安装显卡: "<<gpu<<std::endl;}}voidbuildMonitor(conststd::string&monitor)override{computer_->monitor_=monitor;computer_->price_+=800;std::cout<<"连接显示器: "<<monitor<<std::endl;}voidbuildBluetooth(boolenabled)override{computer_->bluetooth_=enabled;computer_->price_+=enabled?50:0;std::cout<<"配置蓝牙: "<<(enabled?"支持":"不支持")<<std::endl;}voidbuildWifi(boolenabled)override{computer_->wifi_=enabled;computer_->price_+=enabled?80:0;std::cout<<"配置WiFi: "<<(enabled?"支持":"不支持")<<std::endl;}std::unique_ptr<Computer>getResult()override{std::cout<<"办公电脑组装完成!"<<std::endl;returnstd::move(computer_);}};
  1. 指挥者(Director):指导构建过程,但不直接参与具体建造细节。
// 指挥者:指导构建过程classComputerDirector{public:voidconstructGamingComputer(ComputerBuilder&builder){std::cout<<"\n开始构建高性能游戏电脑..."<<std::endl;builder.buildCPU("Intel i9-13900K");builder.buildRAM("32GB DDR5");builder.buildStorage("2TB NVMe SSD");builder.buildGPU("NVIDIA RTX 4080");builder.buildMonitor("32寸4K 144Hz");builder.buildBluetooth(true);builder.buildWifi(true);}voidconstructOfficeComputer(ComputerBuilder&builder){std::cout<<"\n开始构建办公电脑..."<<std::endl;builder.buildCPU("Intel i5-12400");builder.buildRAM("16GB DDR4");builder.buildStorage("512GB SSD");builder.buildGPU("");// 集成显卡builder.buildMonitor("24寸1080P");builder.buildBluetooth(true);builder.buildWifi(true);}voidconstructBasicComputer(ComputerBuilder&builder){std::cout<<"\n开始构建基础电脑..."<<std::endl;builder.buildCPU("Intel i3-12100");builder.buildRAM("8GB DDR4");builder.buildStorage("256GB SSD");builder.buildMonitor("21.5寸1080P");// 不调用 buildGPU, buildBluetooth, buildWifi 使用默认值}};// 使用示例voiddemoBuilderPattern(){std::cout<<"=== 建造者模式演示 ==="<<std::endl;ComputerDirector director;// 构建游戏电脑GamingComputerBuilder gamingBuilder;director.constructGamingComputer(gamingBuilder);autogamingPC=gamingBuilder.getResult();gamingPC->show();// 构建办公电脑OfficeComputerBuilder officeBuilder;director.constructOfficeComputer(officeBuilder);autoofficePC=officeBuilder.getResult();officePC->show();// 自定义构建std::cout<<"\n=== 自定义构建 ==="<<std::endl;GamingComputerBuilder customBuilder;customBuilder.buildCPU("AMD Ryzen 7 7800X3D");customBuilder.buildRAM("64GB DDR5");customBuilder.buildStorage("4TB NVMe SSD");customBuilder.buildGPU("AMD RX 7900 XTX");customBuilder.buildMonitor("34寸曲面带鱼屏");customBuilder.buildBluetooth(true);customBuilder.buildWifi(true);autocustomPC=customBuilder.getResult();customPC->show();}

1.3、建造者模式常见的四个角色

  • Product(产品角色):一个具体的产品对象,比如上面的Computer
  • Builder(抽象建造者):定义构建步骤的接口,比如上面的ComputerBuilder
  • ConcreteBuilder(具体建造者):实现构建步骤,比如上面的GamingComputerBuilder,OfficeComputerBuilder
  • Director(指挥者):指导构建过程以及隔离客户与对象的生产过程,比如上面的ComputerDirector

附上UML类图:

二、总结

2.1、优缺点

优点缺点
构造过程清晰可控增加了代码复杂度
避免伸缩构造函数需要创建多个类
可以分布构建对象适合复杂对象,简单对象不划算
更好的参数验证产品类需要暴露给建造者

2.2、适用场景

  1. 创建复杂对象:对象有很多组成部分,构造过程复杂
  2. 构造过程需要精细控制:需要细化构建步骤
  3. 对象有很多可选参数
  4. 需要创建不同表示的对象:同样的构建过程,不同的配置

2.3、建造者模式 VS 工厂模式

  • 工厂模式:侧重于创建对象,不关心构建过程
  • 建造者模式:侧重于构建过程,不关心对象类型
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 3:38:53

全域众链:需求牵引、政策护航,AI + 实体的落地新路径

在 “AI 赋能实体经济” 的热潮中&#xff0c;真正能扎根市场的项目&#xff0c;必然是兼具需求适配性、政策契合度与落地可行性的务实之作。全域众链正是如此&#xff0c;它以实体商家与创业者的核心需求为出发点&#xff0c;以国家政策为发展依托&#xff0c;用闭环模式与实用…

作者头像 李华
网站建设 2026/9/2 21:16:11

73. 矩阵置零

73. 矩阵置零 已解答 中等 提示 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1…

作者头像 李华
网站建设 2026/9/3 2:12:55

播放器视频后处理实践(二)氛围模式

01 前言 在日常视频播放中&#xff0c;我们经常会遇到这样的问题&#xff1a;视频的长宽比例与设备屏幕不一致&#xff0c;导致画面上下或左右出现黑边。虽然这并不影响视频的正常播放&#xff0c;但从用户体验的角度来看&#xff0c;这些黑边往往打断了视觉的沉浸感&#xff0…

作者头像 李华
网站建设 2026/9/2 23:28:46

FastMCP之Resources

一、什么是资源 资源代表 MCP 客户端可以读取的数据或文件&#xff0c;而资源模板通过允许客户端基于 URI 中传递的参数请求动态生成的资源&#xff0c;扩展了这一概念。 FastMCP 简化了静态和动态资源的定义&#xff0c;主要使用 mcp.resource 装饰器。 当客户端请求资源统一资…

作者头像 李华