模式意图
将一个对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
比如组装电脑的过程,组装过程是相同的,但是可以通过换不同的零部件来组装出不同的主机。
该模式适用于某个对象的构建过程复杂的情况。
用户只需要指定复杂对象的类型就可以获取该对象,不需要知道这个对象的构建过程。
结构
- 抽象建造者类
- 具体建造者类
- 产品类
- 指挥者类,调用具体建造者来创建复杂对象的各个部分,只保证各个对象完整创建或按某种顺序创建,也就是完成装配的过程
例子
生产自行车,自行车包括很多零件,如车架,车座等,车架和车座又有多种品牌,一架自行车可以由各种品牌的组件组建而成
public class Client { public static void main(String[] args) { Director director = new Director(new MobileBuilder()); Bike myBike = director.construct(); System.out.println(myBike.getFrame()); System.out.println(myBike.getSeat()); } } class Bike{ private String frame;//车架 private String seat;//车座 public String getFrame() { return frame; } public void setFrame(String frame) { this.frame = frame; } public String getSeat() { return seat; } public void setSeat(String seat) { this.seat = seat; } } class Director{ private Builder builder; public Director(Builder builder) { this.builder = builder; } //组装自行车 public Bike construct(){ builder.buildFrame(); builder.buildSeat(); return builder.createBike(); } } abstract class Builder{ //protected 保证只有子类能访问,子类都需要创建Bike,声明在父类中提高代码复用性 protected Bike bike = new Bike(); public abstract void buildFrame(); public abstract void buildSeat(); public abstract Bike createBike(); } //具体建造者 class OfoBuilder extends Builder{ @Override public void buildFrame() { bike.setFrame("碳纤维车架"); } @Override public void buildSeat() { bike.setSeat("真皮车座"); } @Override public Bike createBike() { return bike; } } class MobileBuilder extends Builder{ @Override public void buildFrame() { bike.setFrame("铝合金车架"); } @Override public void buildSeat() { bike.setSeat("橡胶车座"); } @Override public Bike createBike() { return bike; } }
与工厂方法模式有点相似。
传给指挥者一个具体的建造者----传给咖啡店一个具体的工厂实例
工厂和建造者的区别
工厂侧重于返回的产品(直接返回产品)
建造者侧重于组装的过程
工厂返回的产品是较为组装较为简单的产品(美式咖啡,拿铁咖啡)
建造者返回的产品是组成复杂的产品(摩拜自行车,ofo自行车)
工厂对于产品的处理可能是简单的加工
建造者对于产品的处理就是复杂的组装
建造者
建造者负责统筹建造者的任务,并转交建造者的产品。
就像工厂方法中的商店类,加奶加糖并且返回咖啡给客户。
优点
缺点
只适用于有组成部分相似,组装过程相似的产品,如果某些产品在这方面差异过大,那么就不能适用于同一个同一套组装算法。
模式扩展
另一种用途是当一个类构造器需要传入很多参数时,创建这个类的实例,代码可读性会很差,也容易对号对错。
以组装手机为例
package com.mode; public class Client { public static void main(String[] args) { Phone phone = new Phone("intel","三星","金士顿","华硕"); } } class Phone{ private String cpu; private String screen; private String memory; private String mainBoard; public Phone(String cpu, String screen, String memory, String mainBoard) { this.cpu = cpu; this.screen = screen; this.memory = memory; this.mainBoard = mainBoard; } public String getCpu() { return cpu; } public void setCpu(String cpu) { this.cpu = cpu; } public String getScreen() { return screen; } public void setScreen(String screen) { this.screen = screen; } public String getMemory() { return memory; } public void setMemory(String memory) { this.memory = memory; } public String getMainBoard() { return mainBoard; } public void setMainBoard(String mainBoard) { this.mainBoard = mainBoard; } @Override public String toString() { return "Phone{" + "cpu='" + cpu + '\'' + ", screen='" + screen + '\'' + ", memory='" + memory + '\'' + ", mainBoard='" + mainBoard + '\'' + '}'; } }
利用建造者模式
package com.mode; public class Client { public static void main(String[] args) { Phone phone = new Phone.Builder() .cpu("intel") .mainBoard("华硕") .memory("金士顿") .screen("三星") .build(); //因为这些方法返回的都是this对象,所以可以使用链式编程 System.out.println(phone); } } class Phone{ private String cpu; private String screen; private String memory; private String mainBoard; private Phone(Builder builder) { this.cpu = builder.cpu; this.screen = builder.screen; this.memory = builder.memory; this.mainBoard = builder.mainBoard; } public String getCpu() { return cpu; } public void setCpu(String cpu) { this.cpu = cpu; } public String getScreen() { return screen; } public void setScreen(String screen) { this.screen = screen; } public String getMemory() { return memory; } public void setMemory(String memory) { this.memory = memory; } public String getMainBoard() { return mainBoard; } public void setMainBoard(String mainBoard) { this.mainBoard = mainBoard; } //静态内部类负责给组件赋值,将建造者的结果直接传给外部 public static final class Builder{ private String cpu; private String screen; private String memory; private String mainBoard; public Builder cpu(String cpu){ this.cpu = cpu; return this; } public Builder screen(String screen){ this.screen = screen; return this; } public Builder mainBoard(String mainBoard){ this.mainBoard = mainBoard; return this; } public Builder memory(String memory){ this.memory = memory; return this; } public Phone build(){ return new Phone(this);//把内部类的Builder对象传给外部给的私有构造器 } } @Override public String toString() { return "Phone{" + "cpu='" + cpu + '\'' + ", screen='" + screen + '\'' + ", memory='" + memory + '\'' + ", mainBoard='" + mainBoard + '\'' + '}'; } }
静态内部类负责将各组件封装起来,最后build方法合成产品并直接返回给调用者。
通过链式编程,更方便给对象赋值。