模式定义
将一个复杂对象的构建与它的表示分离,使得相同的构建过程可以创建不同的表示。
模式结构
Builder:生成器接口,定义创建一个Product对象所需的各个部件的操作。
ConcreteBuilder:具体的生成器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后的产品对象的方法。
Director:指导者,主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象。
Product:产品,表示被生成器构建的复杂对象,包含多个部件。
代码实现
@Data
public class AirShip {
private OrbitalModule orbitalModule; //轨道舱
private Engine engine; //发动机
public void launch(){
System.out.println("发射!");
}
}
@Data
@AllArgsConstructor
class OrbitalModule{
private String name;
}
@Data
@AllArgsConstructor
class Engine {
private String name;
}
public interface AirShipBuilder {
Engine builderEngine();
OrbitalModule builderOrbitalModule();
}
public class SxtAirShipBuilder implements AirShipBuilder {
//StringBuilder, 以后学习XML解析中,JDOM库中的类:DomBuilder,SaxBuilder
public Engine builderEngine() {
System.out.println("构建发动机!");
return new Engine("发动机!");
}
public OrbitalModule builderOrbitalModule() {
System.out.println("构建轨道舱");
return new OrbitalModule("轨道舱");
}
}
public interface AirShipDirector {
/**
* 组装飞船对象
* @return
*/
AirShip directAirShip();
}
public class SxtAirshipDirector implements AirShipDirector {
private AirShipBuilder builder;
public SxtAirshipDirector(AirShipBuilder builder) {
this.builder = builder;
}
public AirShip directAirShip() {
Engine e = builder.builderEngine();
OrbitalModule o = builder.builderOrbitalModule();
//装配成飞船对象
AirShip ship = new AirShip();
ship.setEngine(e);
ship.setOrbitalModule(o);
return ship;
}
}
public class Client {
public static void main(String[] args) {
AirShipDirector director = new SxtAirshipDirector(new SxtAirShipBuilder());
AirShip ship = director.directAirShip();
System.out.println(ship.getEngine().getName());
ship.launch();
}
}
模式的优缺点
优点
松散耦合
产品构建和产品表现分离。可以很容易地改变产品的内部表示
要想改变产品的内部表示,只需要切换Builder的具体实现即可,不用管Director,因此变得容易。更好的复用性
构建算法可以复用,具体产品的实现也可以复用。
缺点
建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。
思考
模式本质:分离整体构建算法和部件构造。
开发中的应用场景
如果构讲对象的算法,应该独立于该对象的组成部分以及它们的装配方式时。
如果同一个构建过程有着不同的表示时。
构建的过程是同一的,不变的,变化的部分放到生成器部分