前言
Builder模式是将对象的构建和表示分离,好比构建一辆汽车,Builder是将部件和组装过程分离,从而达到高内聚低耦合的目的。
使用场景
1.相同的方法,结果和执行顺序有关。
2.多个部件都可以组装到一个对象中,但是结果和这个部件有关。
3.产品非常复杂,或者初始化对象非常复杂(参数太多)。
简单的代码实现
Build分为Products产品类(产品的抽象类)、Builder类(规范产品的组建,但一般不实现具体过程)、ConcreteBuilder类(具体实现Builder类抽象方法)、Director类(统一组装类,多数情况下都会省略该类)。
抽象一个生产过程:宝马汽车的组装,简单分为几步(组装汽车外壳、组装汽车中控、组装汽车发动机等机械部件、内饰)。
Product类
package com.demo.bulider;
/**
* Created by italkbb on 2017/12/13.
*/
public abstract class BMWCar {
// 汽车外壳
protected String mShell;
// 汽车多媒体中控
protected String mControl;
// 汽车引擎和其他机械部件
protected String mEngineAndOthers;
// 汽车内饰
protected String mDecoration;
protected BMWCar(){
}
// 转配汽车外壳
public void setShell(String mShell) {
this.mShell = mShell;
}
// 装配汽车多媒体中控
public void setControl(String mControl) {
this.mControl = mControl;
}
// 装配汽车机械部件
public void setEngineAndOthers() {
}
// 装配汽车内饰
public void setDecoration(String mDecoration) {
this.mDecoration = mDecoration;
}
}
这个类定义产品,但是并不去装配产品,只是定义一个规则,那么我们想要组装一台X6汽车,这里先抽象的设置X6和一般宝马汽车最大的不同是发动机和机械组件,所以一上来我们的生产工人先把各型号的发动机组装好,这个是技术活,当然给高级工程师,不需要装配工人介入了。
package com.demo.bulider;
/**
* Created by italkbb on 2017/12/13.
*/
public class BMWX6Car extends BMWCar{
protected BMWX6Car(){
}
// 抽象为X6区别就是发动机等主要机械组件不一样
@Override
public void setEngineAndOthers() {
mEngineAndOthers = "宝马X6专用发动机";
}
}
宝马汽车的主要部分已经好了,那么把这个大框架给到组装工人去做外层处理,再定义一个生产规则:(Builder类)
package com.demo.bulider;
/**
* Created by italkbb on 2017/12/13.
*/
public abstract class Builder {
// 设置外壳
public abstract Builder buliderShell(String shell);
// 设置中控系统
public abstract Builder buliderControl(String control);
// 装置机械组件
public abstract Builder buliderEngineAndOthers();
// 装配内饰
public abstract Builder buliderDecoration(String decoration);
// 出厂汽车
public abstract BMWCar create();
}
这当时组装经理定义好了规则,下发给下一级员工。(下面说具体的Bulider类)
package com.demo.bulider;
/**
* Created by italkbb on 2017/12/13.
*/
public class BMWX6Bulider extends Builder{
private BMWCar mBMWCar = new BMWX6Car();
@Override
public Builder buliderShell(String shell) {
mBMWCar.setShell(shell);
return this;
}
@Override
public Builder buliderControl(String control) {
mBMWCar.setControl(control);
return this;
}
@Override
public Builder buliderEngineAndOthers() {
mBMWCar.setEngineAndOthers();
return this;
}
@Override
public Builder buliderDecoration(String decoration) {
mBMWCar.setDecoration(decoration);
return this;
}
@Override
public BMWCar create() {
return mBMWCar;
}
}
为了满足生产线流水工作,组长把这个组装过程封装了一下,只要员工按规矩来就能够组装好,而且组装过程变得非常简单,员工只需要把组装的原件放到指定位置就OK(Director类)。
package com.demo.bulider;
/**
* Created by italkbb on 2017/12/13.
*/
public class Director {
Builder mBulider = null;
public Director(Builder builder){
this.mBulider = builder;
}
/**
* 统一组装,简化生产步骤
* @param shell
* @param control
* @param decoration
* @return
*/
public BMWCar createCar(String shell,String control,String decoration){
return mBulider.buliderShell(shell)
.buliderControl(control)
.buliderEngineAndOthers()
.buliderDecoration(decoration).create();
}
}
在实际开发中,其实可以不要Director类,因为组装过程已经很简单,员工知道掉builder的方法的教育成本已经很低了,所以开发中往往省略该类。
总结
builder模式在Android开发中也常常会用到,比如我之前加密解密Imageloader,里面单例模式和Builder模式为主,还有Android源码里面AlertDialog.Builder类,这里就不贴相关代码了,说一下优缺点:该模式封装的比较好,就像组装汽车,组员工可以不必知道内部是怎么实现的,只需要按着说明书把相关零件放到指定位置;其次,如果要给Builder添加构建方法也变得很容易,这叫易于扩展吧。当然缺点也显而易见:实现一个汽车组装用到了五个类,其实真要写,一个类都能够实现这个过程,只是代码清晰度差点。我的邮箱redzkh@gmail.com,有错误还望指正。