1、概述
建造者模式多用在对象构成比较复杂的场景中,比如汽车、电脑等包含的组件数量和种类很多很大的情形下。建造者(Builder)模式的定义如下,把一个复杂对象的构造与它的装配分离,使同样的构造过程可以创建不同的装配,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象(小的组件),然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
由于实现了构建和装配的解耦,不同的构建器相同的装配,可以产生不同的对象;相同的构建器,不同的装配顺序也可以产生不同的对象,从而实现了代码复用。
2、接口和类层次结构
(1)产品和组件类:此类中定义一个public产品类和若干个非public的产品组件类
(2)构造接口:接口中定义了多个方法,每个方法返回值类型对应一个组件类
(3)装配接口:接口中定义了一个方法,方法的返回值类型为产品类
(4)构造接口的实现类:实现接口中的每个方法即可
(5)装配接口的实现类:首先需要在此类中定义两个变量,一个是构造接口类型的变量,另一个是产品类,并重写构造方法。在实现装配接口中方法体的过程中,利用构造接口类型的变量来构造各个组件,利用装配接口类型的变量来装配产品。最终返回组装成功的产品即可。
以上讲述比较抽象,可以结合以下案例来进行理解:
(1)产品和组件类:一个public修饰的产品类Laptop,若干个非public的产品组件类CPU类、Monitor类和Keyboard类。
(2)构造接口(PartBuilder):定义一个PartBuilder接口,接口中定义了返回值类型分别为CPU、Monitor、Keyboard的三个方法createCPU();createMonitor();createKeyboard();
(3)装配接口(LaptopDirector):接口中定义了一个返回类型为Laptop的方法createLaptop();
(4)构造接口的实现类(RealizationPartBuillder):实现构造接口中的createCPU();createMonitor()和createKeyboard();三个方法即可
(5)装配接口的实现类(RealizationLaptopDirector):定义一个构造接口类型(RealizationPartBuillder)的变量builder和一个产品类类型(Laptop)的变量laptop,在实现装配接口中的方法createLaptop()时,通过builder的三个方法createCPU();createMonitor();createKeyboard();来创建三个组件CPU、Monitor和Keyboard,然后通过laptop中的方法来装配三个组件即可完成一个商品laptop的构造和装配,最终返回laptop即可
以上过程可能有点混乱,但是把握住两条主线可能会容易理解:此模式中实现了构造和装配解耦,构造是一个线,此线中需要定义构造接口和构造接口的实现类;装配是另外一个线,同样也需要定义装配接口和装配接口的实现类。但是解耦并不代表两条线没有任何联系,事实上,在最终的装配阶段,装配过程是需要使用构造过程的“产品的”,也即构造过程生产出各个组件(子零件),装配过程复杂把这写组件装配成最终的产品。
3、代码展示(与上述过程是对应的)
(1)产品和组件类
package com.builder;
//组装的产品类Laptop,是由CPU,Monitor,Keyboard组成
//so需要单独定义三个类CPU,Monitor,Keyboard,作为Laptop的成员
public class Laptop {
public CPU getCpu() {
return cpu;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
public Monitor getMonitor() {
return monitor;
}
public void setMonitor(Monitor monitor) {
this.monitor = monitor;
}
public Keyboard getKeyboard() {
return keyboard;
}
public void setKeyboard(Keyboard keyboard) {
this.keyboard = keyboard;
}
private CPU cpu;
private Monitor monitor;
private Keyboard keyboard;
public void start() {
System.out.println("Start successfully");
}
}
class CPU{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public CPU(String name) {
this.name = name;
}
}
class Monitor{
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String name;
public Monitor(String name) {
this.name = name;
}
}
class Keyboard{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Keyboard(String name) {
this.name= name;
}
}
(2)构造接口(PartBuilder)
package com.builder;
public interface PartBuilder {
CPU createCPU();
Monitor createMonitor();
Keyboard createKeyboard();
}
(3)装配接口(LaptopDirector)
package com.builder;
public interface LaptopDirector {
Laptop createLaptop();
}
(4)构造接口的实现类(RealizationPartBuillder)
package com.builder;
public class RealizationPartBuillder implements PartBuilder {
@Override
public CPU createCPU() {
// TODO Auto-generated method stub
System.out.println("CPU is created");
return new CPU("A new CPU");
}
@Override
public Monitor createMonitor() {
// TODO Auto-generated method stub
System.out.println("Monitor is created");
return new Monitor("A new Monitor");
}
@Override
public Keyboard createKeyboard() {
// TODO Auto-generated method stub
System.out.println("Keyboard is created");
return new Keyboard("A new Keyboard");
}
}
(5)构造接口的实现类(RealizationPartBuillder)
package com.builder;
public class RealizationLaptopDirector implements LaptopDirector {
private RealizationPartBuillder builder;
public RealizationLaptopDirector(RealizationPartBuillder builder) {
this.builder = builder;
}
@Override
public Laptop createLaptop() {
// TODO Auto-generated method stub
CPU cpu = builder.createCPU();
Monitor monitor = builder.createMonitor();
Keyboard keyboard = builder.createKeyboard();
Laptop laptop = new Laptop();
laptop.setCpu(cpu);
laptop.setKeyboard(keyboard);
laptop.setMonitor(monitor);
return laptop;
}
}
(6)测试主类:
package com.builder;
public class Client {
public static void main(String args[]) {
RealizationPartBuillder partBuilder = new RealizationPartBuillder();
RealizationLaptopDirector laptopBuilder = new RealizationLaptopDirector(partBuilder);
Laptop laptop = laptopBuilder.createLaptop();
System.out.println(laptop);
}
}
(7)运行结果:
CPU is created
Monitor is created
Keyboard is created
com.builder.Laptop@15db9742
4、总结
建造者模式中实现了类的组件的构造和装配分离,而且各个具体的建造者相互独立,有利于系统的扩展,对于对象的构建过程复杂的情况特别适用。