
主要讲解建造者builder模式和实际应用的场景基于java。最low方法我们通过一个例子来引出Builder模式。我们需要通过builder模式构建企鹅对象penguin企鹅有很多属性比如姓名、年龄、性别和身高该类的定义如下public class penguin { private String name; private Integer age; private String sex; private Integer heignt; public void setName(String name) { this.name name; } public void setAge(Integer age) { this.age age; }; public void setSex(String sex) { this.sex sex; } public void setHeignt(Integer heignt) { this.heignt heignt; }; public void print() { String str name: name; str (age null) ? : ,age: age; str (sex null) ? : ,sex: sex; str (heignt null) ? : ,age: heignt; System.out.println(str); } }为了构建不同属性特性的企鹅我们通常会这么写构造器public penguin(String name) { this.name name; } public penguin(String name, Integer age) { this.name name; this.age age; } public penguin(String name, Integer age, String sex) { this.name name; this.age age; this.sex sex; } public penguin(String name, Integer age, String sex, Integer heignt) { this.name name; this.age age; this.sex sex; this.heignt heignt; }然后开始去初始化自己想要的企鹅对象public static void main(String[] args) { penguin penguin1 new penguin(楼仔); penguin penguin2 new penguin(楼仔, 18); penguin penguin3 new penguin(楼仔, 18, 男); penguin penguin4 new penguin(楼仔, 18, 男, 180); penguin1.print(); penguin2.print(); penguin3.print(); penguin4.print(); }输出结果为name:楼仔 name:楼仔,age:18 name:楼仔,age:18,sex:男 name:楼仔,age:18,sex:男,age:180这种方式比较常规但是如果我只想初始化name和hight你可能还需要再新增新的构造器不过有的同学可能会说“我才不用构造器初始化对象我可以用类提供的setxxx()来设置对应的属性值”但是这种做法不会觉得很冗余么每个属性都用setxxx()设置一下如果有十几个属性值你是不是要用setxxx()全部设置一遍呢这时候如果换一个角度试试Builder模式你会发现代码的可读性一下子就上去了。builder模式我们给penguin增加一个静态内部类penguinBuilder类并修改penguin类的构造函数代码如下public class penguin { private String name; private Integer age; private String sex; private Integer heignt; public void print() { String str name: name; str (age null) ? : ,age: age; str (sex null) ? : ,sex: sex; str (heignt null) ? : ,age: heignt; System.out.println(str); } public penguin(penguinBuilder builder) { this.age builder.age; this.name builder.name; this.sex builder.sex; this.heignt builder.heignt; } public static class penguinBuilder { private String name; private Integer age; private String sex; private Integer heignt; public penguinBuilder setName(String name) { this.name name; return this; } public penguinBuilder setAge(Integer age) { this.age age; return this; } public penguinBuilder setSex(String sex) { this.sex sex; return this; } public penguinBuilder setHeignt(Integer heignt) { this.heignt heignt; return this; } public penguin bulid() { return new penguin(this); } } }这样我们就不会被penguin类构造函数的各个入参搞得稀里糊涂了。此外penguinBuilder类中的成员函数返回penguinBuilder对象自身让它支持链式调用使代码可读性大大增强。于是我们就可以这样创建penguin类。public static void main(String[] args) { penguin penguin1 new penguin.penguinBuilder().setName(楼仔). setSex(男). setHeignt(170). setAge(18). bulid(); penguin penguin2 new penguin.penguinBuilder().setName(楼仔). setAge(18). bulid(); penguin1.print(); penguin2.print(); }有没有觉得创建过程一下子就变得那么清晰了对应的值是什么属性一目了然可读性大大增强输出如下name:楼仔,age:18,sex:男,age:170 name:楼仔,age:18综上我们总结一下build模式的要点定义一个静态内部类Builder内部的成员变量和外部类一样Builder类通过一系列的方法用于成员变量的赋值并返回当前对象本身thisBuilder类提供一个外部类的创建方法build、create……该方法内部调用了外部类的一个私有构造函数入参就是内部类Builder外部类提供一个私有构造函数供内部类调用在该构造函数中完成成员变量的赋值取值为Builder对象中对应的成变量的值。吐槽的方法这个其实是最标准的builder模式也是菜鸟教程展示的示例我的示例和他基本上异曲同工我只是拿出来吐槽不推荐大家使用仅了解即可。这个是菜鸟画的图其实原理和上面讲的都一样唯一的区别就是多了一个Director这个Director是干啥用的呢其实就是把组建对象的过程都放到这里面实现文字不好理解我们直接看代码public class penguin { private String name; private Integer age; private String sex; private Integer heignt; public void setName(String name) { this.name name; } public void setAge(Integer age) { this.age age; }; public void setSex(String sex) { this.sex sex; } public void setHeignt(Integer heignt) { this.heignt heignt; }; public static class penguinBuilder { // 这里初始化penguin对象 private penguin m_penguin new penguin(); public penguinBuilder setName(String name) { this.m_penguin.setName(name); return this; } public penguinBuilder setAge(Integer age) { this.m_penguin.setAge(age); return this; } public penguinBuilder setSex(String sex) { this.m_penguin.setSex(sex); return this; } public penguinBuilder setHeignt(Integer heignt) { this.m_penguin.setHeignt(heignt); return this; } public penguin bulid() { return this.m_penguin; } } }下面就是标准builder的重点多了Directorpublic class director { penguin.penguinBuilder m_builder; public director(penguin.penguinBuilder build) { this.m_builder build; } public penguin construct(String name, Integer age, String sex, Integer height) { return this.m_builder.setAge(age). setHeignt(height). setName(name). setSex(sex). bulid(); } }所以这个Director其实就是将builder作为对象成员然后通过builder在Director中去构造对象示例只是构造方式的一种你也可以通过你自己的方式去定制化这个penguin的构造。所以你可以理解标准的builder是把penguin的构造放入Director中非标准的就是直接在builder中直接构造penguin对象。最后的使用姿势如下public static void main(String[] args) { penguin.penguinBuilder builder new penguin.penguinBuilder(); director penguinDirector new director(builder); penguin penguin1 penguinDirector.construct(楼仔, 18,男 , 170); penguin1.print(); }这个就是菜鸟给我的示例然后按照这种方式给我讲解builder模式然后我居然还看到网上有同学把这个模式按照菜鸟的讲解自己实现了一遍然后给大家讲解builder如果大家对builder模式停留在这里我敢肯定下次代码需要重构时你绝对不会想到用builder模式去优化你的代码。相反我直接通过非Director的方式实现builder模式然后支持链式调用这个才能真实解决我的问题。所以设计模式不是死记硬背引用同事告知的一句话不迷信设计模式借鉴思想好用最重要实际场景这个很多场景都会使用也就是当你需要初始化一个对象但是对象里面有一堆成员变量比如有10个左右你如果给每个成员调用set方法去赋值代码可读性就太差了这时可以采用builder模式让这些成员的赋值通过链式的方式去set值然后通过bulider去生成一个完整的对象。