设计模式Java实现-建造者模式
2024/5/8 23:02:45
本文主要是介绍设计模式Java实现-建造者模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
楔子
小七在2019年的时候,就想写一个关于设计模式的专栏,但是最终却半途而废了。粗略一想,如果做完一件事要100分钟,小七用3分钟热情做的事,最少也能完成10件事情了。所以这一次,一定要把他做完,fighting!
需求背景
以以前小七做的一个政务系统为例,为了符合国标,数据库表需要设计很多字段,大概有100多个。每次new这个实体的时候,都会调用大量的set方法,关键是这100个字段基本不会变,但是他们的组合却经常变,弄得开发的小伙伴们苦不堪言,于是前辈们就重载了很多的构造方法,结果构造方法也爆炸了,导致新来的后浪们差点直接被拍死在了沙滩上。
为了简化代码,咱们这一次就定义一个Student类,里面只包含name和age。
分析设计
因为这个对象的属性很多,且组合方式很自由,如果使用经典的new-set方式,代码大概如下:
BigObject bigObject = new BigObject(); bigObject.setO1(""); bigObject.setO2(""); bigObject.setO3(""); bigObject.setO4(""); bigObject.setO5(""); bigObject.setO6(""); bigObject.setO7(""); bigObject.setO8(""); bigObject.setO9(""); bigObject.setO10(""); ... bigObject.setO100("");
看起来并不直观。
如果每一个组合就重载一个构造方法,也会产生很多构造方法,并且语义不明,新来的小伙伴会一脸懵逼。
但是如果我们能够抽象一下产品的构建过程,具体建造者类继承自抽象建造者类,实现具体的构建逻辑。指挥者类负责调用具体建造者类的构建方法,完成产品的构建。这样就可以降低客户端代码的复杂度,提高代码的可维护性。
定义 | 类名 |
---|---|
产品类 | Student |
抽象建造者类 | StudentBuilder |
具体建造者类 | StudentActualBuilder |
指挥者类 | Commander |
标准建造者模式
UML图
根据分析设计,我们可以先画一个简单的UML图,后面通过UML图编码
模块名称
builder.demo01
模块地址
https://gitee.com/diqirenge/design-pattern/tree/master/src/main/java/com/run2code/design/creational/builder/demo01
模块描述
经典模式代码示例
代码实现
1、定义产品类
/** * 定义产品类 * 关注公众号【奔跑的码畜】,一起进步不迷路 * * @author 第七人格 * @date 2023/11/20 */ public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
2、定义抽象建造者类
/** * 定义抽象建造者类 * 关注公众号【奔跑的码畜】,一起进步不迷路 * * @author 第七人格 * @date 2023/11/20 */ public abstract class StudentBuilder { public abstract void buildName(String name); public abstract void buildAge(int age); public abstract Student makeStudent(); }
3、定义具体建造者类
/** * 定义具体建造者类 * 关注公众号【奔跑的码畜】,一起进步不迷路 * * @author 第七人格 * @date 2023/11/20 */ public class StudentActualBuilder extends StudentBuilder { /** * 这里使用组合,将 student 组合到实现类中 */ private Student student = new Student(); @Override public void buildName(String name) { student.setName(name); } @Override public void buildAge(int age) { student.setAge(age); } @Override public Student makeStudent() { return student; } }
4、定义指挥者类
/** * 定义指挥者类 * 关注公众号【奔跑的码畜】,一起进步不迷路 * * @author 第七人格 * @date 2023/11/20 */ public class Commander { /** * 注入StudentBuilder */ private StudentBuilder studentBuilder; public void setStudentBuilder(StudentBuilder studentBuilder) { this.studentBuilder = studentBuilder; } public Student makeStudent(String name, int age) { this.studentBuilder.buildAge(age); this.studentBuilder.buildName(name); return this.studentBuilder.makeStudent(); } }
5、测试
public class BuilderStudentBuilderTest { @Test public void testBuild_01() { System.out.println("==========标准建造者模式开始=========="); StudentActualBuilder studentActualBuilder = new StudentActualBuilder(); Commander commander = new Commander(); commander.setStudentBuilder(studentActualBuilder); // 客户端使用指挥者类创建产品对象,这样可以降低客户端代码的复杂度,提高代码的可维护性。 Student student = commander.makeStudent("第七人格", 18); System.out.println(student); System.out.println("==========标准建造者模式结束=========="); } }
6、测试结果
==标准建造者模式开始==
Student{name=‘第七人格’, age=18}
==标准建造者模式结束==
实现要点
-
定义产品类:产品类是最终要构建的对象,包含多个属性和方法。
-
定义抽象建造者类:抽象建造者类定义了产品的构建过程,包括各个部分的构建方法和返回最终产品的方法。
-
定义具体建造者类:具体建造者类继承自抽象建造者类,实现具体的构建逻辑。
-
定义指挥者类:指挥者类负责调用具体建造者类的构建方法,完成产品的构建。
用过StringBuilder的我们知道,StringBuilder有个append方法,我们学着StringBuilder将上面的代码,改为链式调用。
链式调用模式
URL图
模块名称
builder.demo02
模块地址
https://gitee.com/diqirenge/design-pattern/tree/master/src/main/java/com/run2code/design/creational/builder/demo02
模块描述
建造者-链式调用
代码实现
/** * 链式调用建造者示例 * 关注公众号【奔跑的码畜】,一起进步不迷路 * * @author 第七人格 * @date 2023/11/20 */ public class Student02Builder { /** * 姓名 */ private String name; /** * 年龄 */ private int age; /** * 学生类的构造函数 * * @param name 的名字 * @param age 年龄 */ Student02Builder(String name, int age) { this.name = name; this.age = age; } /** * 构建器(本质上就是指挥者Commander) * * @return {@link StudentBuilder} */ public static Student02Builder.StudentBuilder builder() { // 构造一个StudentBuilder对象 return new Student02Builder.StudentBuilder(); } /** * 学生构建器(相当于StudentBuilder及其实现类StudentActualBuilder) * * @author 第七人格 * @date 2020/12/02 */ public static class StudentBuilder { private String name; private int age; public StudentBuilder() { } public Student02Builder.StudentBuilder name(String name) { this.name = name; // 返回自身(StudentBuilder),以便链式调用 return this; } public Student02Builder.StudentBuilder age(int age) { this.age = age; // 返回自身(StudentBuilder),以便链式调用 return this; } /** * 构建 * * @return {@link Student02Builder} */ public Student02Builder build() { // 构造一个Student对象,其中的属性直接从外部传入 return new Student02Builder(this.name, this.age); } @Override public String toString() { return "Student.StudentBuilder(name=" + this.name + ", age=" + this.age + ")"; } } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
测试
@Test public void testBuild_02() { System.out.println("==========工作中常用-建造者模式开始=========="); System.out.println(Student02Builder.builder() .age(18) .name("第七人格") .build() ); System.out.println("==========工作中常用-建造者模式开始=========="); }
测试结果
==链式调用-建造者模式开始==
Student{name=‘第七人格’, age=18}
==链式调用-建造者模式开始==
实现要点
1、使用静态方法替换指挥者Commander
public static Student02Builder.StudentBuilder builder() { // 构造一个StudentBuilder对象 return new Student02Builder.StudentBuilder(); }
2、使用内部类替换StudentBuilder及StudentActualBuilder
3、内部类中设置属性的时候,返回自身,以便链式调用
面对对象面对君,不负代码不负卿
这篇关于设计模式Java实现-建造者模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-19永别了,微服务架构!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?