本文根据光头强做电锯的故事,讲解一下Java设计模式中的“建造者模式”,故事性更强,配合着代码讲解,让大家更轻松的掌握“建造者模式”。
熊出没 第59集 超级电锯
建造者模式它是一种 将复杂对象的构造与其表示分开,以便相同的构造过程可以创建不同的表示
的设计模式。
一个完整的建造者模式分为4个部分:
一般用于复杂的对象内部,比如:一个对象有多个功能,可以在它的内部用多个方法具体描述每个功能,然后调用这个类的时候,就可以直自由的构建出这个类对象(比如: new Person().setName("18").setAge(20).build();
其实这个Person类就做了具体的对象构建的操作逻辑。),也有网友狭隘的说 链式调用
就是建造者模式,其实那是片面的认识,虽然是一种表现形式,但是实际操作中有很多不同的表现形式,不能一概而论。下面就一个实例详解一下基本使用到复杂多变的使用场景。
光头强于是去了镇子上的五金店铺,,光头强心理嘀咕着:“不光能砍树,还能吓跑熊大熊二,看它还敢来欺负自己。”于是跟那个老板的说了自己的需求:“我要买一把电手锯”。老板说:“不好意思,没有了,需要预定,预计一个星期之后就到了。”然后光头强就下单了,老板就电话通知手电锯工厂下了订单,然后工厂开始生产手电锯。
这回还没把熊大熊二吓跑,于是光头强又跑到镇子上,找到了五金店的老板,让老板给他一把厉害的锯子。光头强这回跟那个老板的说了自己的需求:“我要一把厉害的电手锯,上回那个没有赶走熊大熊二,你这里有没有厉害的手电锯”。老板逐个都介绍了一遍,光头强一对比,发现并没有自己想要的独一无二的那个。于是跟那个老板的说了自己的需求:“我需要的是这样的:调速防误触智能开关、动力强耐高温散热好的纯铜电机、环保大容量锂电池、人体工体学包胶防滑防抖手柄、环保防触电插头、加厚加固耐磨抗打击防护罩、高硬度锯片、然后额外配上LED灯,钱不是问题”。老板说没问题,半个月之后过来取吧。光头强于是交了定金,兴奋的回家了。坐等老板的好消息了。
车间要准备要投入生产的机器,还有各种原材料和模具:
/** * 链锯建筑者 */ public interface ChainsawBuilder { // 蓄电池 void battery(); // 电动机 void motor(); // 减速箱 void reductionGearbox(); // 防护罩 void hood(); // 手柄 void handle(); // 开关 void switches(); // 插头 void plug(); // 圆锯片 void circularSaw(); // 获取链锯(产品)的实例 Chainsaws getChainsaws(); } 复制代码
接下来就是具体的车间按照现有的材料进行生产:
/** * 链锯建筑者(具体建筑者) */ public class ChainsawBuilderImpl implements ChainsawBuilder{ private Chainsaws chainsaws; public ChainsawBuilderImpl() { chainsaws = new Chainsaws(); } @Override public void battery() { chainsaws.setBattery("普通锂电池"); } @Override public void motor() { chainsaws.setMotor("普通铝电动机"); } @Override public void reductionGearbox() { chainsaws.setReductionGearbox("普通减速箱"); } @Override public void hood() { chainsaws.setHood("普通PVC塑料"); } @Override public void handle() { chainsaws.setHandle("普通PVC塑料"); } @Override public void switches() { chainsaws.setSwitches("普通拉线开关"); } @Override public void plug() { chainsaws.setPlug("普通三口插头"); } @Override public void circularSaw() { chainsaws.setCircularSaw("普通钢锯片"); } @Override public Chainsaws getChainsaws() { return chainsaws; } } 复制代码
最终产品就具备这些功能:
/** * 产品(链锯) */ public class Chainsaws { // 蓄电池 private String battery; // 电动机 private String motor; // 减速箱 private String reductionGearbox; // 防护罩 private String hood; // 手柄 private String handle; // 开关 private String switches; // 插头 private String plug; // 圆锯片 private String circularSaw; public String getBattery() { return battery; } public void setBattery(String battery) { this.battery = battery; } public String getMotor() { return motor; } public void setMotor(String motor) { this.motor = motor; } public String getReductionGearbox() { return reductionGearbox; } public void setReductionGearbox(String reductionGearbox) { this.reductionGearbox = reductionGearbox; } public String getHood() { return hood; } public void setHood(String hood) { this.hood = hood; } public String getHandle() { return handle; } public void setHandle(String handle) { this.handle = handle; } public String getSwitches() { return switches; } public void setSwitches(String switches) { this.switches = switches; } public String getPlug() { return plug; } public void setPlug(String plug) { this.plug = plug; } public String getCircularSaw() { return circularSaw; } public void setCircularSaw(String circularSaw) { this.circularSaw = circularSaw; } @Override public String toString() { return "Chainsaws{" + "/n battery='" + battery + '/'' + ", motor='" + motor + '/'' + ", reductionGearbox='" + reductionGearbox + '/'' + ", hood='" + hood + '/'' + ", handle='" + handle + '/'' + ", switches='" + switches + '/'' + ", plug='" + plug + '/'' + ", circularSaw='" + circularSaw + '/'' + "链锯已经做好了/n" + '}'; } } 复制代码
老板作为一个中间人的角色,需要跟厂商对接,电话通知建造方,查看进度如何了:
/** * 五金店老板(验收方) */ public class HardwareStoreBoss { // 电话通知建造方,查看进度如何了 public Chainsaws notify(ChainsawBuilder builder){ // 蓄电池 builder.battery(); // 电动机 builder.motor(); // 减速箱 builder.reductionGearbox(); // 防护罩 builder.hood(); // 手柄 builder.handle(); // 开关 builder.switches(); // 插头 builder.plug(); // 圆锯片 builder.circularSaw(); return builder.getChainsaws(); } } 复制代码
过了几天,光头强打电话给五金店老板。
HardwareStoreBoss hardwareStoreBoss = new HardwareStoreBoss(); 复制代码
五金店老板跟光头强说你等会儿,我先去问问链锯做好了没,于是:
Chainsaws chainsaws = hardwareStoreBoss.notify(new ChainsawBuilderImpl()); System.out.println(chainsaws.toString()); 复制代码
这时候打印结果是:
Chainsaws{ battery='普通锂电池', motor='普通铝电动机', reductionGearbox='普通减速箱', hood='普通PVC塑料', handle='普通PVC塑料', switches='普通拉线开关', plug='普通三口插头', circularSaw='普通钢锯片'链锯已经做好了 } 复制代码
然后五金店老板去生产那里取货,然后再通知光头强过去取货。
光头强拿到货之后,就兴高采烈的去试着砍树,结果发现砍了几棵树,要么就是没电了,要么就是掉链子了,这怎么行?光头强这回要求老板退货,老板不干,这样吧。我给你返回维修。维修费我出。光头强不干,坚决要退货,老板犟不过,要不这样,给你换一个性能更高级的链锯,你只要补差价就好了,怎么样,工厂那边正好有批次在做的,给你预定一个,一周内可以就拿到货了。光头强爽快的答应了。
于是工厂这边也利用原有的功能(接口ChainsawBuilder),加入新的一些功能(新建一个类ChainsawBuilderImpl2),就开始制造了。基本功能都差不多的,只是换一些零部件,如下所示:
/** * 链锯建筑者(具体建筑者) */ public class ChainsawBuilderImpl2 implements ChainsawBuilder{ private Chainsaws chainsaws; public ChainsawBuilderImpl2() { chainsaws = new Chainsaws(); } @Override public void battery() { chainsaws.setBattery("环保大容量锂电池"); } @Override public void motor() { chainsaws.setMotor("动力强耐高温散热好的纯铜电机"); } @Override public void reductionGearbox() { chainsaws.setReductionGearbox("减震变频高功率变速箱"); } @Override public void hood() { chainsaws.setHood("加厚加固耐磨抗打击防护罩"); } @Override public void handle() { chainsaws.setHandle("人体工体学包胶手柄"); } @Override public void switches() { chainsaws.setSwitches("调速防误触智能开关"); } @Override public void plug() { chainsaws.setPlug("环保防触电插头"); } @Override public void circularSaw() { chainsaws.setCircularSaw("高硬度锯片"); } @Override public Chainsaws getChainsaws() { return chainsaws; } } 复制代码
同样的过了几天,光头强打电话给五金店老板。
HardwareStoreBoss hardwareStoreBoss = new HardwareStoreBoss(); 复制代码
五金店老板跟光头强说你等会儿,我先去问问链锯(这时候是:新链锯)做好了没,于是:
Chainsaws chainsaws = hardwareStoreBoss.notify(new ChainsawBuilderImpl2()); System.out.println(chainsaws.toString()); 复制代码
这时候打印结果是:
Chainsaws{ battery='环保大容量锂电池', motor='动力强耐高温散热好的纯铜电机', reductionGearbox='减震变频高功率变速箱', hood='加厚加固耐磨抗打击防护罩', handle='人体工体学包胶手柄', switches='调速防误触智能开关', plug='环保防触电插头', circularSaw='高硬度锯片'链锯已经做好了 } 复制代码
于是光头强就去拿到新链锯愉快的砍树去了。
光头强发现一个链锯不够用了,还想再买一个,但是每次通过五金店老板去询问太麻烦了,于是通过网上官网查询,找到了生产厂家的售后电话,直接联系他们,又重新定制了一个链锯。
厂家看光头强已经是第三次购买,算是VIP用户了,特意为他开了一个后门,车间有同意协调(链锯建造者类)专门管理。
/** * 链锯建筑者 */ public interface ChainsawBuilder { // 蓄电池 ChainsawBuilder battery(String name); // 电动机 ChainsawBuilder motor(String name); // 减速箱 ChainsawBuilder reductionGearbox(String name); // 防护罩 ChainsawBuilder hood(String name); // 手柄 ChainsawBuilder handle(String name); // 开关 ChainsawBuilder switches(String name); // 插头 ChainsawBuilder plug(String name); // 圆锯片 ChainsawBuilder circularSaw(String name); // 获取链锯(产品)的实例 Chainsaws getChainsaws(); } 复制代码
这样一来,可以快速由专人负责找到对应的零件。
具体的生产建筑者这边也没闲着,也跟着做了改变,之前是规矩写死的,我这里有什么,客户才能定制什么(方法传入的String类型的参数),现在是可互需要的是什么,我这边就负责生产什么样的。具体如下:
/** * 链锯建筑者(具体建筑者) */ public class ChainsawBuilderImpl2 implements ChainsawBuilder { private Chainsaws chainsaws; public ChainsawBuilderImpl2() { chainsaws = new Chainsaws(); } @Override public ChainsawBuilder battery(String name) { chainsaws.setBattery(name); return this; } @Override public ChainsawBuilder motor(String name) { chainsaws.setMotor(name); return this; } @Override public ChainsawBuilder reductionGearbox(String name) { chainsaws.setReductionGearbox(name); return this; } @Override public ChainsawBuilder hood(String name) { chainsaws.setHood(name); return this; } @Override public ChainsawBuilder handle(String name) { chainsaws.setHandle(name); return this; } @Override public ChainsawBuilder switches(String name) { chainsaws.setSwitches(name); return this; } @Override public ChainsawBuilder plug(String name) { chainsaws.setPlug(name); return this; } @Override public ChainsawBuilder circularSaw(String name) { chainsaws.setCircularSaw(name); return this; } @Override public Chainsaws getChainsaws() { return chainsaws; } } 复制代码
光头强这时候想问厂家做好了没,告诉厂家自己要做的零部件的类型,厂家就一次性安排生产了:
ChainsawBuilderImpl2 chainsawBuilderImpl2 = new ChainsawBuilderImpl2(); Chainsaws chainsaws = chainsawBuilderImpl2.battery("环保大容量锂电池") .motor("动力强耐高温散热好的纯铜电机") .reductionGearbox("减震变频高功率变速箱") .hood("加厚加固耐磨抗打击防护罩") .handle("人体工体学包胶手柄") .switches("调速防误触智能开关") .plug("环保防触电插头") .circularSaw("高硬度锯片") .getChainsaws(); 复制代码
这时候打印结果还是一样的:
Chainsaws{ battery='环保大容量锂电池', motor='动力强耐高温散热好的纯铜电机', reductionGearbox='减震变频高功率变速箱', hood='加厚加固耐磨抗打击防护罩', handle='人体工体学包胶手柄', switches='调速防误触智能开关', plug='环保防触电插头', circularSaw='高硬度锯片'链锯已经做好了 } 复制代码