创建型模式 - 建造者模式 (Builder Pattern)

devtools/2025/2/26 12:19:17/

创建型模式 - 建造者模式 (Builder Pattern)

建造者模式是一种创建型设计模式,它将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。


需求描述
在游戏开发中,创建一个复杂的游戏角色,角色具有多种属性,如姓名、性别、职业、武器等。不同类型的角色这些属性的组合和设置方式可能不同。使用建造者模式可以将角色的创建过程和具体表示分离,方便创建不同类型的角色。

java">// 产品类:游戏角色
class GameCharacter {private String name;private String gender;private String profession;private String weapon;public void setName(String name) {this.name = name;}public void setGender(String gender) {this.gender = gender;}public void setProfession(String profession) {this.profession = profession;}public void setWeapon(String weapon) {this.weapon = weapon;}@Overridepublic String toString() {return "GameCharacter{" +"name='" + name + '\'' +", gender='" + gender + '\'' +", profession='" + profession + '\'' +", weapon='" + weapon + '\'' +'}';}
}// 抽象建造者类
abstract class CharacterBuilder {protected GameCharacter character;public GameCharacter getCharacter() {return character;}public void createNewCharacter() {character = new GameCharacter();}public abstract void buildName();public abstract void buildGender();public abstract void buildProfession();public abstract void buildWeapon();
}// 具体建造者类:战士角色建造者
class WarriorBuilder extends CharacterBuilder {@Overridepublic void buildName() {character.setName("战士-亚瑟");}@Overridepublic void buildGender() {character.setGender("男");}@Overridepublic void buildProfession() {character.setProfession("战士");}@Overridepublic void buildWeapon() {character.setWeapon("大剑");}
}// 具体建造者类:法师角色建造者
class MageBuilder extends CharacterBuilder {@Overridepublic void buildName() {character.setName("法师-梅林");}@Overridepublic void buildGender() {character.setGender("男");}@Overridepublic void buildProfession() {character.setProfession("法师");}@Overridepublic void buildWeapon() {character.setWeapon("法杖");}
}// 指挥者类
class CharacterDirector {private CharacterBuilder builder;public CharacterDirector(CharacterBuilder builder) {this.builder = builder;}public GameCharacter constructCharacter() {builder.createNewCharacter();builder.buildName();builder.buildGender();builder.buildProfession();builder.buildWeapon();return builder.getCharacter();}
}// 客户端代码
public class GameCharacterBuilderExample {public static void main(String[] args) {// 创建战士角色CharacterBuilder warriorBuilder = new WarriorBuilder();CharacterDirector warriorDirector = new CharacterDirector(warriorBuilder);GameCharacter warrior = warriorDirector.constructCharacter();System.out.println(warrior);// 创建法师角色CharacterBuilder mageBuilder = new MageBuilder();CharacterDirector mageDirector = new CharacterDirector(mageBuilder);GameCharacter mage = mageDirector.constructCharacter();System.out.println(mage);}
}

建造者模式拓展

使用这一种方式,就相当于代码中调用方法者来充当指挥者角色。

java">public class Phone {private String cpu;private String screen;private String memory;private String brand;// 私有构造函数private Phone(Builder builder) {this.cpu = builder.cpu;this.screen = builder.screen;this.memory = builder.memory;	this.brand = builder.brand;}// 内部类构造器public static final class Builder {private String cpu;private String screen;private String memory;private String brand;public Builder cpu(String cpu) {this.cpu = cpu;return this;}public Builder screen(String screen) {this.screen = screen;return this;}public Builder memory(String memory) {this.memory = memory;return this;}public Builder brand(String brand) {this.brand = brand;return this;}// 利用 Java 内部类可以访问外部类的私有成员变量的特性,调用私有构造方法返回 Phone 对象public Phone build() {return new Phone(this);}}
}// 使用的时候非常方便也非常清晰
Phone iPhone20 = new Phone.Builder().cpu("Apple A100").screen("LG屏幕").memory("三星内存").brand("Apple").build();// btw: 这种使用方式还是挺常见的, 在一些第三方库配置 Config 的时候,例如 Rocket MQ 配置

小结
工厂方法模式 vs 建造者模式.
工厂方法注重的是整体的构建.
建造者模式注重零部件细节的过程.

抽象工厂模式 vs 建造者模式
抽象工厂注重的是相同的产品家族同一系列产品的构建。不关心构建过程,不同的产品交给不同的具体工厂去构建.
举例,苹果电脑工厂,你知道结果就是一台苹果电脑。而如果使用建造者模式.你需要知道每个零件由什么构成.你使用不同的零件组装出来的就是不同的电脑.


http://www.ppmy.cn/devtools/162783.html

相关文章

EntityFrameCore CodeFirst 迁移

CodeFirst 代码先行,只关心业务,需要什么对象就写什么对象; Nuget引入程序集 Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.SqlServer Microsoft.EntityFrameworkCore.SqlServer.Design Microsoft.EntityFrameworkCore.To…

kafka队列堆积的常见解决

1. 检查生产者是否正常工作 如果生产者速度太慢或者不稳定,可以通过增加生产者吞吐量来解决。 解决方案: 提高生产者的吞吐量:可以通过调整生产者配置来增加吞吐量。 设置生产者 acks 参数为 1 或 0(如果不需要严格的消息确认&…

uniapp小程序自定义日历(签到、补签功能)

1、切换月份根据当前月判断,只能切换当前月份之前的时间。 2、补卡功能,根据后台设置自己写上即可,可补签多少天。 3、点击签到是签到当前天的,不能指定签到时间。 备注:当前代码只构建了排版样式和切换月份功能&…

RAG技术落地:核心痛点与应对策略全面解析

RAG技术落地:核心痛点与应对策略全面解析 RAG技术落地:核心痛点与应对策略全面解析一、技术实现层的四大挑战二、数据质量管理的生死线三、产业落地的软性痛点四、未来技术演进方向 RAG技术落地:核心痛点与应对策略全面解析 检索增强生成&a…

UE(虚幻)学习(五)初学创建NPC移动和遇到的问题

最近在学习UE中遇到一些问题,把这些问题记录一下,因为实在废了很大功夫。 在学习了UE5的例子中的第三人称移动Demo,想实现几个NPC在场景内移动。 本来想自己写一个类,遇到一堆问题花费了好几天时间,所以我把问题写下来…

【qt计算器】

qt计算器 目录注释部分模块配置目标配置模板配置源文件配置头文件配置UI 文件配置1. 头文件保护宏2. 包含必要的头文件3. 命名空间声明4. 类的定义5. 构造函数和析构函数6. 私有槽函数7. 私有成员变量8. 头文件保护宏结束1. 包含头文件2. 构造函数 MainWindow::MainWindow(QWid…

使用机器学习进行土地覆盖分类

土地利用和土地覆盖 (LULC) 分类在林业和农业领域发挥着重要作用,无论是种植园管理、生态系统恢复、碳市场计划还是其他应用。监测土地覆盖和土地利用变化是特许权所有者的一项强制性任务,需要对其特许权区域进行一致且准确的分析。 作为一名 GIS 分析师…

数据结构——排序2

今天,我们来讲解一下选择排序和冒泡排序还有堆排序。 选择排序的基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。 下图中只选取了它…