一、描述
建筑者(builder)也是创建模式的一种,最原始的意思是建筑房屋的工人。可以想象一下如果需要建造房子必须先打地基---->构建框架----->垒墙---->装修等等。它是有一定的流程顺序的,而每一步的实现可以单独一个模块出来。所以,由此可以得出Builder模式主要适用于:
- 需要创建的产品由N个模块构成并且需要按照某种顺序,不关注各模块的实现,但构成顺序对它来说非常重要。
- 也可以是没有顺序的组装对象。
二、实现
该模式一般有以下几个模块构成:
- 需要组装的对象
- 抽象Builder定义build()方法用于协议构成对象的顺序。
- 具体的Builder实现类,用于实现各模块功能
无顺序
可以在组装的对象内部类来实现,例如:一台电脑的组成。
public class Computer {
//电脑构成的模块
private List<String> parts = new ArrayList<String>();
//电脑的类型
private Type type;
public Computer(Type type){
this.type = type;
}
public enum Type{
DESKTOP,NOTEBOOK,PAD
}
public void addPart(String partBand){
parts.add(partBand);
}
//拼装打印结果
public String finished(){
StringBuilder builder = new StringBuilder("类型:"+type);
for(String s:parts) {
builder.append("-->"+s);
}
return builder.toString();
}
//初始化取得builder对象
public static Builder init(Type type){
return new Builder(type);
}
//简单的builder类,业务简单时可以不使用抽象
static class Builder{
private Type type;
//构建的具体模块
private String cpu;
private String mainboard;
private String store;
private String screen;
public Builder(Type type) {
this.type = type;
}
//构建完成后返回当前对象,组成链式的效果(类似jquery)
public Builder setType(Type type) {
this.type = type;
return this;
}
public Builder setCpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder setMainboard(String mainboard) {
this.mainboard = mainboard;
return this;
}
public Builder setStore(String store) {
this.store = store;
return this;
}
public Builder setScreen(String screen) {
this.screen = screen;
return this;
}
//按某种顺序来构建对象(当然这个只讨论电脑的组成部件没有顺序)
public Computer build(){
Computer c = new Computer(type);
c.addPart(cpu);
c.addPart(mainboard);
c.addPart(store);
c.addPart(screen);
return c;
}
}
//测试
public static void main(String []args) {
Computer c = Computer.init(Type.DESKTOP)
.setCpu("inter i7")
.setMainboard("华硕")
.setStore("西部数据")
.setScreen("三星")
.build();
System.out.println(c.finished());
}
}
有顺序
比如,建筑一座房子。
抽象的建造者,保证建造房子的顺序,不会出现先垒墙后打地基的错误。
public abstract class AbsBuilder {
abstract AbsBuilder build_diji();
abstract AbsBuilder build_kuangjia();
abstract AbsBuilder build_leiqiang();
abstract AbsBuilder build_zhuangshi();
protected House house;
AbsBuilder(House house){
this.house = house;
}
public House build(){
build_diji();
build_kuangjia();
build_leiqiang();
build_zhuangshi();
return house;
}
}
为了简单可以内部类
public class House {
private String type;
House(String type) {
this.type = type;
}
private List<String> houseList = new ArrayList<String>();
public void addPart(String part) {
houseList.add(part);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder("房屋类型:"+type+",开始建造:");
for(String s:houseList) {
builder.append("-->"+s);
}
return builder.toString();
}
public static AbsBuilder startBuildHightHouse(){
return new HightHouseBuilder(new House("高楼"));
}
public static AbsBuilder startBungalowBuilder(){
return new HightHouseBuilder(new House("平房"));
}
public static class HightHouseBuilder extends AbsBuilder{
HightHouseBuilder(House house) {
super(house);
}
@Override
AbsBuilder build_diji() {
house.addPart("建立地基");
return this;
}
@Override
AbsBuilder build_kuangjia() {
house.addPart("建立框架");
return this;
}
@Override
AbsBuilder build_leiqiang() {
house.addPart("垒墙");
return this;
}
@Override
AbsBuilder build_zhuangshi() {
house.addPart("装修");
return this;
}
}
public static class bungalowBuilder extends AbsBuilder{
bungalowBuilder(House house) {
super(house);
}
@Override
AbsBuilder build_diji() {
house.addPart("建立地基");
return this;
}
@Override
AbsBuilder build_kuangjia() {
house.addPart("建立框架");
return this;
}
@Override
AbsBuilder build_leiqiang() {
house.addPart("垒墙");
return this;
}
@Override
AbsBuilder build_zhuangshi() {
house.addPart("装修");
return this;
}
}
public static void main(String []args) {
House house = House.startBuildHightHouse()
.build();
System.out.println(house);
house = House.startBungalowBuilder()
.build();
System.out.println(house);
}
}
总结
在开发项目的时候经常会使用此模式来收集构建一些基本属性,链式的操作使得操作更加的简洁、直观。同时,也易于扩展和维护,即使是一个新手接手项目也能够一眼看出代码的意思。