目录

前言

一、什么是建造者模式

二、建造者模式的结构

三、建造者模式应用场景

参考文章


前言

在听完厉风行老师《设计模式系列课程》中的建造者模式一节后顿时感觉有点头大,感觉它有点像工厂方法模式,查看了网上很多文章也是众说纷纭,看到了corn的这篇文章才有点拨开云雾见晴天的感觉。

http://www.cnblogs.com/lwbqqyumidi/p/3742562.html

一、什么是建造者模式

建造者(Builder)模式也叫生成器模式,是由GoF提出的23种设计模式中的一种,其设计意图是:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

GoF给出的描述很简短,不易理解,我是这样理解的:我们要创建的对象会包含有各种各样的属性(可以是对象,也可以不是对象,就好比汽车的零配件),这些属性就叫做这个对象的表示,有了属性之后我们还需要将这些属性按照一定的规则或者顺序组装起来才能创造出对象来(这就好比用汽车零件组装汽车),而这个组装的过程就是对象的构建,Builder模式将对象的表示与对象的构建分别交由建造者和指挥者去负责,整个对象的创建过程对客户端是隐藏的,客户端只需要去调用建造者和指挥者去创建对象,而不必关系这个对象都有哪些属性,以及各个属性之间是怎么样进行组装的,达到了责任划分和封装的目的。

二、建造者模式的结构

建造者模式适合于创建比较复杂的对象,所谓复杂有两个方向:
- 创建过程复杂,创建的步骤有严格的顺序。
- 创建对象的结构复杂,创建对象包含的属性数量多。

针对以上两类的复杂对象Builder模式也分别演化出了两种表现形式。

第一种

通过Product、ConcreteBuilder、Builder和Director形成的建造者模式。

Builder示意图

从上图可以看出,这种Builder模式包含4个角色:产品(Product),具体建造者(ConcreteBuilder),建造者(Builder),指挥者(Director)

产品:需要创建的对象产品
建造者:本质为抽象类,里面的抽象方法供具体建造者重写。
具体建造者:创建产品的实例并且实现建造者多个方法对产品进行装配。
指挥者:有条不紊的按顺序调用建造者抽象类及其方法。

我们都知道计算机重装系统是一件很复杂的事情,首先你要备份重要数据、格式化硬盘,安装操作系统,然后再拷贝数据,安装驱动,安装常用软件,等等…,接下来我们就以重装计算机操作系统为例来体会一下Builder模式的作用。
我们需要一个类来说明安装后的系统要包含哪些东西,这个类就是我们要创建的产品类。

public class SysApplication {
	// 系统中的文件数据
	private String data;
	// 操作系统
	private String operationSystem;
	// 驱动
	private String driver;
	// 包含哪些有用的软件
	private String usefulSoftware;
	public String getData() {
		return data;
	}
	public void setData(String data) {
		this.data = data;
	}
	public String getOperationSystem() {
		return operationSystem;
	}
	public void setOperationSystem(String operationSystem) {
		this.operationSystem = operationSystem;
	}
	public String getDriver() {
		return driver;
	}
	public void setDriver(String driver) {
		this.driver = driver;
	}
	public String getUsefulSoftware() {
		return usefulSoftware;
	}
	public void setUsefulSoftware(String usefulSoftware) {
		this.usefulSoftware = usefulSoftware;
	}
}



再创建一个ISysInstallBuilder接口把重装系统过程中我们要做的事情都罗列出来,这个接口就扮演了Builder模式中的建造者角色。

public interface ISysInstallBuilder {
	// 备份数据
	public void backupdata();
	// 格式化硬盘
	public void formatDisk();
	// 复制数据
	public void copyData();
	// 安装操作系统
	public void installOperationSystem();
	// 安装驱动
	public void installDriver();
	// 安装有用的软件
	public void installUsefulSoftware();
	// 获取安装好的系统
	public SysApplication getSystemApplication();
}



接下来我们来实现安装Windows XP系统的具体建造者类WinXpInstallBuilder,以后需要安装Windows XP系统就用它。

public class WinXpInstallBuilder implements ISysInstallBuilder {
	private SysApplication systemApplication = new SysApplication();
	@Override
	public void backupdata() {
		// 此处填写数据备份相关代码
		System.out.println("备份数据");
	}
	@Override
	public void formatDisk() {
		// 此处填写硬盘格式化相关代码
		System.out.println("格式化硬盘");
	}
	@Override
	public void copyData() {
		// 此处填写复制数据相关代码
		System.out.println("复制数据");
		this.systemApplication.setData("原系统备份的数据");
	}
	@Override
	public void installOperationSystem() {
		// 此处填写安装Windows XP操作系统相关代码
		System.out.println("安装Windows XP操作系统");
		this.systemApplication.setOperationSystem("Windows XP");
	}
	@Override
	public void installDriver() {
		// 此处填写安装Windows XP驱动相关代码
		System.out.println("安装Windows XP驱动");
		this.systemApplication.setDriver("Windows XP驱动");
	}
	@Override
	public void installUsefulSoftware() {
		// 此处填写安装Windows XP操作系统下常用软件相关代码
		System.out.println("安装Windows XP操作系统下常用软件");
		this.systemApplication.setUsefulSoftware("Windows XP操作系统下常用软件");
	}
	@Override
	public SysApplication getSystemApplication() {
		// 将安装好的系统返回
		return this.systemApplication;
	}
}



现在我们有了一个具体建造者类WinXpInstallBuilder,接下来我们尝试着用它来重装一下系统。

public class MainClass {
	public static void main(String[] args) {
		// 创建一个WinXpInstallBuilder
		ISysInstallBuilder builder = new WinXpInstallBuilder();
		// 调用WinXpInstallBuilder,开始装系统了
		builder.backupdata();
		builder.copyData();
		builder.formatDisk();
		builder.installDriver();
		builder.installOperationSystem();
		builder.installUsefulSoftware();
		// 获取到安装好的系统
		SysApplication sysApplication = builder.getSystemApplication();
		System.out.println("----------系统信息如下----------");
		System.out.println("数据:" + sysApplication.getData());
		System.out.println("驱动:" + sysApplication.getDriver());
		System.out.println("操作系统:" + sysApplication.getOperationSystem());
		System.out.println("软件:" + sysApplication.getUsefulSoftware());
	}
}



运行程序打印结果如下:

备份数据
复制数据
格式化硬盘
安装Windows XP驱动
安装Windows XP操作系统
安装Windows XP操作系统下常用软件
----------系统信息如下----------
数据:原系统备份的数据
驱动:Windows XP驱动
操作系统:Windows XP
软件:Windows XP操作系统下常用软件

细心的你可能发现了,我安装的这个系统是有问题的,我把系统安装步骤的顺序搞乱了,复制数据应该放在格式化硬盘并安装好操作系统之后,安装驱动应该放在安装操作系统之后。由于安装系统的步骤比较复杂,虽然我已经很小心翼翼可还是把安装步骤给搞错了,怎样才能让系统按照正确的步骤安装而不会搞乱顺序呢?到了指挥者出场的时刻了。

public class SysInstallDirector {
	private ISysInstallBuilder builder;
	public SysInstallDirector(ISysInstallBuilder builder) {
		this.builder = builder;
	}
	public void installSystem() {
		builder.backupdata();
		builder.formatDisk();
		builder.installOperationSystem();
		builder.installDriver();
		builder.installUsefulSoftware();
		builder.copyData();
	}
}

接下来我们再使用指挥者装一次系统试试。

public class Client{
	public static void main(String[] args) {
		// 创建一个WinXpInstallBuilder
		ISysInstallBuilder builder = new WinXpInstallBuilder();
		//创建一个指挥者
		SysInstallDirector director = new SysInstallDirector(builder);
		//建造者在指挥者的指挥下开始安装系统了
		director.installSystem();
		// 从建造者手里获取到安装好的系统
		SysApplication sysApplication = builder.getSystemApplication();
		System.out.println("----------系统信息如下----------");
		System.out.println("数据:" + sysApplication.getData());
		System.out.println("驱动:" + sysApplication.getDriver());
		System.out.println("操作系统:" + sysApplication.getOperationSystem());
		System.out.println("软件:" + sysApplication.getUsefulSoftware());
	}
}

运行程序打印结果如下:

数据备份
硬盘格式化
安装Windows XP操作系统
安装Windows XP驱动
安装Windows XP操作系统下常用软件
复制数据
----------系统信息如下----------
数据:原系统备份的数据
驱动:Windows XP驱动
操作系统:Windows XP
软件:Windows XP操作系统下常用软件

在有了指挥者的帮忙后,系统按照正确的顺序安装完成了。

接下来我们再实现一个安装Win7系统的具体建造者类Win7InstallBuilder。

public class Win7InstallBuilder implements ISysInstallBuilder {
	private SysApplication systemApplication = new SysApplication();
	@Override
	public void backupdata() {
		// 此处填写数据备份相关代码
		System.out.println("数据备份");
	}
	@Override
	public void formatDisk() {
		// 此处填写硬盘格式化相关代码
		System.out.println("硬盘格式化");
	}
	@Override
	public void copyData() {
		// 此处填写复制数据相关代码
		System.out.println("复制数据");
		this.systemApplication.setData("原系统备份的数据");
	}
	@Override
	public void installOperationSystem() {
		// 此处填写安装安装Win7操作系统相关代码
		System.out.println("安装Win7操作系统");
		this.systemApplication.setOperationSystem("Win7");
	}
	@Override
	public void installDriver() {
		// 此处填写安装安装Win7驱动相关代码
		System.out.println("安装Win7驱动");
		this.systemApplication.setDriver("Win7驱动");
	}
	@Override
	public void installUsefulSoftware() {
		// 此处填写安装安装Win7操作系统下常用软件相关代码
		System.out.println("安装Win7操作系统下常用软件");
		this.systemApplication.setUsefulSoftware("Win7操作系统下常用软件");
	}
	@Override
	public SysApplication getSystemApplication() {
		// 将安装好的系统返回
		return this.systemApplication;
	}
}

在客户端中测试一下安装Win7系统。

public class Client{
	public static void main(String[] args) {
		// 创建一个Win7InstallBuilder
		ISysInstallBuilder builder = new Win7InstallBuilder();
		// 创建一个指挥者
		SysInstallDirector director = new SysInstallDirector(builder);
		// 建造者在指挥者的指挥下开始安装系统了
		director.installSystem();
		// 从建造者手里获取到安装好的系统
		SysApplication sysApplication = builder.getSystemApplication();
		System.out.println("----------系统信息如下----------");
		System.out.println("数据:" + sysApplication.getData());
		System.out.println("驱动:" + sysApplication.getDriver());
		System.out.println("操作系统:" + sysApplication.getOperationSystem());
		System.out.println("软件:" + sysApplication.getUsefulSoftware());
	}
}

运行程序打印结果如下:

数据备份
硬盘格式化
安装Win7操作系统
安装Win7驱动
安装Win7操作系统下常用软件
复制数据
----------系统信息如下----------
数据:原系统备份的数据
驱动:Win7驱动
操作系统:Win7
软件:Win7操作系统下常用软件

Win7系统也被正确安装,Builder模式通过指挥者和建造者将要创建的对象属性和属性的装配过程进行分离,一样的创建过程由于传入的具体建造者不同最终创建出了完全不同的对象,而且无需再担忧把组装顺序搞混了。

第二种

通过静态内部类实现复杂对象的无序构造。

创建一个个人信息类PersonalInfo,其中包含个人信息包括:电话号码,地址,姓名,年龄,性别,身份证号。

public class PersonalInfo {
	private String name;
	private int age;
	private String gender;
	private String address;
	private String iDNumber;
	private String phoneNumber;
	public String getPhoneNumber() {
		return phoneNumber;
	}
	public String getAddress() {
		return address;
	}
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	public String getGender() {
		return gender;
	}
	public String getIDNumber() {
		return iDNumber;
	}
	public static class Builder {
		private String name;
		private int age;
		private String gender;
		private String address;
		private String iDNumber;
		private String phoneNumber;
		public Builder(String name) {
			this.name = name;
		}
		public Builder phoneNumber(String phoneNumber) {
			this.phoneNumber = phoneNumber;
			return this;
		}
		public Builder address(String address) {
			this.address = address;
			return this;
		}
		public Builder age(int age) {
			this.age = age;
			return this;
		}
		public Builder gender(String gender) {
			this.gender = gender;
			return this;
		}
		public Builder iDNumber(String iDNumber) {
			this.iDNumber = iDNumber;
			return this;
		}
		public PersonalInfo build() {
			return new PersonalInfo(this);
		}
	}
	private PersonalInfo(Builder builder) {
		this.address = builder.address;
		this.age = builder.age;
		this.gender = builder.gender;
		this.iDNumber = builder.iDNumber;
		this.name = builder.name;
		this.phoneNumber = builder.phoneNumber;
	}
}

在客户端中使用此类创建个人信息测试一下。

public class Client{
	public static void main(String[] args) {
		PersonalInfo personalInfo = new PersonalInfo.Builder("姬如雪")
				.address("幻音坊").age(19).gender("女").build();
		System.out.println("------------个人信息----------------");
		System.out.println("姓名:"+personalInfo.getName());
		System.out.println("住址:"+personalInfo.getAddress());
		System.out.println("年龄:"+personalInfo.getAge());
		System.out.println("性别:"+personalInfo.getGender());
	}
}

运行程序打印结果如下:

------------个人信息----------------
姓名:姬如雪
住址:幻音坊
年龄:19
性别:女

此种方式通过级联方式去创建对象,可自由控制创建对象的属性个数,减少了重复代码,使对象的创建更加形象直观。

三、建造者模式应用场景

如果碰到以下情况,可以考虑使用建造者模式:
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
- 当构造过程必须允许被构造的对象有不同的表示时。
- 创建的是一个复合对象:被创建的对象为一个具有复合属性的复合对象

参考文章

http://www.cnblogs.com/lwbqqyumidi/p/3742562.html

Java开发的就业市场正在经历结构性调整,竞争日益激烈

传统纯业务开发岗位(如仅完成增删改查业务的后端工程师)的需求,特别是入门级岗位,正显著萎缩。随着企业技术需求升级,市场对Java人才的要求已从通用技能转向了更深入的领域经验(如云原生、微服务)或前沿的AI集成能力。这也导致岗位竞争加剧,在一、二线城市,求职者不仅面临技术内卷,还需应对学历与项目经验的高门槛。

大模型为核心的AI领域正展现出前所未有的就业热度与人才红利

2025年,AI相关新发岗位数量同比激增543%,单月增幅最高超过11倍,大模型算法工程师位居热门岗位前列。行业顶尖人才的供需严重失衡,议价能力极强,跳槽薪资涨幅可达30%-50%。值得注意的是,市场并非单纯青睐算法研究员,而是急需能将大模型能力落地于复杂业务系统的工程人才。这使得具备企业级架构思维和复杂系统整合经验的Java工程师,在向“Java+大模型”复合人才转型时拥有独特优势,成为企业竞相争夺的对象,其薪资天花板也远高于传统Java岗位。

在这里插入图片描述

说真的,这两年看着身边一个个搞Java、C++、前端、数据、架构的开始卷大模型,挺唏嘘的。大家最开始都是写接口、搞Spring Boot、连数据库、配Redis,稳稳当当过日子。

结果GPT、DeepSeek火了之后,整条线上的人都开始有点慌了,大家都在想:“我是不是要学大模型,不然这饭碗还能保多久?”

先给出最直接的答案:一定要把现有的技术和大模型结合起来,而不是抛弃你们现有技术!掌握AI能力的Java工程师比纯Java岗要吃香的多。

即使现在裁员、降薪、团队解散的比比皆是……但后续的趋势一定是AI应用落地!大模型方向才是实现职业升级、提升薪资待遇的绝佳机遇!

如何学习AGI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版CSDN大礼包:《AGI大模型学习资源包》免费分享**

一、2025最新大模型学习路线

一个明确的学习路线可以帮助新人了解从哪里开始,按照什么顺序学习,以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛,没有明确的学习路线可能会导致新人感到迷茫,不知道应该专注于哪些内容。

我们把学习路线分成L1到L4四个阶段,一步步带你从入门到进阶,从理论到实战。

L1级别:AI大模型时代的华丽登场

L1阶段:我们会去了解大模型的基础知识,以及大模型在各个行业的应用和分析;学习理解大模型的核心原理,关键技术,以及大模型应用场景;通过理论原理结合多个项目实战,从提示工程基础到提示工程进阶,掌握Prompt提示工程。

L2级别:AI大模型RAG应用开发工程

L2阶段是我们的AI大模型RAG应用开发工程,我们会去学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。

L3级别:大模型Agent应用架构进阶实践

L3阶段:大模型Agent应用架构进阶实现,我们会去学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造我们自己的Agent智能体;同时还可以学习到包括Coze、Dify在内的可视化工具的使用。

L4级别:大模型微调与私有化部署

L4阶段:大模型的微调和私有化部署,我们会更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调;并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。

整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握;而L3 L4更多的是通过项目实战来掌握大模型的应用开发,针对以上大模型的学习路线我们也整理了对应的学习视频教程,和配套的学习资料。

二、大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

三、大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

四、大模型项目实战

学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

五、大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版CSDN大礼包:《AGI大模型学习资源包》免费分享

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐