建造者设计模式
建造者模式
建造者模式也是非常常见的一种设计模式,我们经常看到有很多的框架都为我们提供了形如XXXBuilder
的类型,我们一般也是使用这些类来创建我们需要的对象。
比如,我们在JavaSE中就学习过的StringBuiler
类:
public static void main(String[] args) { StringBuilder builder = new StringBuilder(); //创建一个StringBuilder来逐步构建一个字符串 builder.append(666); //拼接一个数字 builder.append("老铁"); //拼接一个字符串 builder.insert(2, '?'); //在第三个位置插入一个字符 System.out.println(builder.toString()); //差不多成形了,最后转换为字符串 }
实际上我们是通过建造者来不断配置参数或是内容,当我们配置完所有内容后,最后再进行对象的构建。
相比直接去new一个新的对象,建造者模式的重心更加关注在如何完成每一步的配置,同时如果一个类的构造方法参数过多,我们通过建造者模式来创建这个对象,会更加优雅。
比如我们现在有一个学生类:
1 2 3 4 5 6 7 8 | class Student { private int id; private int age; private String name; private String college; private String profession; private List<String> hobby; } |
可以看到这个学生类的属性是非常多的,所以构造方法不是一般的长,如果我们现在直接通过new的方式去创建:
1 2 3 | public static void main(String[] args) { Student student = new Student( 1 , 18 , "小明" , "计算机学院" , "学生" , Arrays.asList( "抽烟" , "喝酒" , "烫头" )); } |
可以看到,我们光是填参数就麻烦,我们还得一个一个对应着去填,一不小心可能就把参数填到错误的位置了。
所以,我们现在可以使用建造者模式来进行对象的创建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | class Student { private int id; private int age; private String name; private String college; private String profession; private List<String> hobby; // 设置为私有,只给内部类用 private Student( int id, int age, String name, String college, String profession, List<String> hobby) { this .id = id; this .age = age; this .name = name; this .college = college; this .profession = profession; this .hobby = hobby; } /** * 获取建造者 * * @return 建造者 */ public static StudentBuild build() { return new StudentBuild(); } public int getId() { return id; } public void setId( int id) { this .id = id; } public int getAge() { return age; } public void setAge( int age) { this .age = age; } public String getName() { return name; } public void setName(String name) { this .name = name; } public String getCollege() { return college; } public void setCollege(String college) { this .college = college; } public String getProfession() { return profession; } public void setProfession(String profession) { this .profession = profession; } public List<String> getHobby() { return hobby; } public void setHobby(List<String> hobby) { this .hobby = hobby; } @Override public String toString() { return "Student{" + "id=" + id + ", age=" + age + ", name='" + name + '\ '' + ", college='" + college + '\ '' + ", profession='" + profession + '\ '' + ", hobby=" + hobby + '}' ; } public static class StudentBuild { //Builder也需要将所有的参数都进行暂时保存,所以Student怎么定义的这里就怎么定义 private int id; private int age; private String name; private String college; private String profession; private List<String> hobby; // 这里返回this是为了链式调用 public StudentBuild id( int id) { this .id = id; return this ; } public StudentBuild age( int age) { this .age = age; return this ; } public StudentBuild name(String name) { this .name = name; return this ; } public StudentBuild college(String college) { this .college = college; return this ; } public StudentBuild profession(String profession) { this .profession = profession; return this ; } public StudentBuild hobby(String... hobby) { this .hobby = Arrays.asList(hobby); return this ; } public Student build() { return new Student(id, age, name, college, profession, hobby); } } } |
现在,我们就可以使用建造者来为我们生成对象了:
1 2 3 4 5 6 7 8 9 10 11 12 | public static void main(String[] args) { Student student = Student.build() .id( 1 ) .age( 23 ) .name( "张三" ) .college( "信息工程学院" ) .profession( "学生" ) .hobby( "抽烟" , "喝酒" , "烫头" ) .build(); //Student{id=1, age=23, name='张三', college='信息工程学院', profession='学生', hobby=[抽烟, 喝酒, 烫头]} System.out.println(student); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话