建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式其实就是使用多个简单对象一步步的创建一个复杂对象。用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)。
建造者模式符合依赖倒置原则:
- 高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
- 抽象不应该依赖于具体实现,具体实现应该依赖于抽象。
建造者模式UML类图:
- Builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。
- ConcreteBuilder:实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例。
- Director:聚合关联Builder,调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
- Product:要创建的复杂对象。
建造者模式代码:
//Director接口
interface AirShipDirector {
//组装船对象
AirShip directAirShip();
}
//Builder接口
interface AirShipBuilder {
Engine builderEngine();
OrbitalModule builderOrbitalModule();
EscapeTower builderEscapeTower();
}
//Builder实现类
class SxtAirShipBuilder implements AirShipBuilder {
@Override
public Engine builderEngine() {
System.out.println("构建飞天发动机!");
return new Engine("飞天发动机!");
}
@Override
public EscapeTower builderEscapeTower() {
System.out.println("构建逃逸塔");
return new EscapeTower("飞天逃逸塔");
}
@Override
public OrbitalModule builderOrbitalModule() {
System.out.println("构建轨道舱");
return new OrbitalModule("飞天轨道舱");
}
}
//Director实现类
class SxtAirshipDirector implements AirShipDirector {
private AirShipBuilder builder;
public SxtAirshipDirector(AirShipBuilder builder) {
this.builder = builder;
}
@Override
public AirShip directAirShip() {
Engine e = builder.builderEngine();
OrbitalModule o = builder.builderOrbitalModule();
EscapeTower et = builder.builderEscapeTower();
//装配成飞船对象
AirShip ship = new AirShip();
ship.setEngine(e);
ship.setEscapeTower(et);
ship.setOrbitalModule(o);
return ship;
}
}
//实体类
class AirShip {
private OrbitalModule orbitalModule; //轨道舱
private Engine engine; //发动机
private EscapeTower escapeTower; //逃逸塔
public OrbitalModule getOrbitalModule() {
return orbitalModule;
}
public void setOrbitalModule(OrbitalModule orbitalModule) {
this.orbitalModule = orbitalModule;
}
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
public EscapeTower getEscapeTower() {
return escapeTower;
}
public void setEscapeTower(EscapeTower escapeTower) {
this.escapeTower = escapeTower;
}
@Override
public String toString() {
return "AirShip{" +
"orbitalModule=" + orbitalModule +
", engine=" + engine +
", escapeTower=" + escapeTower +
'}';
}
}
//轨道舱对象
class OrbitalModule{
private String name;
public OrbitalModule(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "OrbitalModule{" +
"name='" + name + '\'' +
'}';
}
}
//发动机对象
class Engine {
private String name;
public Engine(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Engine{" +
"name='" + name + '\'' +
'}';
}
}
//逃逸塔对象
class EscapeTower{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EscapeTower(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "EscapeTower{" +
"name='" + name + '\'' +
'}';
}
}
public class ShipBuilder {
public static void main(String[] args) {
AirShipDirector director = new SxtAirshipDirector(new SxtAirShipBuilder());
AirShip ship = director.directAirShip();
System.out.println(ship);
}
}
运行結果:
- 构建飞天发动机!
- 构建轨道舱
- 构建逃逸塔
- AirShip{orbitalModule=OrbitalModule{name='飞天轨道舱'}, engine=Engine{name='飞天发动机!'}, escapeTower=EscapeTower{name='飞天逃逸塔'}}
建造者模式优点:
- 易于解耦 :将产品本身与产品创建过程进行解耦,可以使用相同的创建过程来得到不同的产品。也就说细节依赖抽象。
- 易于精确把控对象的创建 :将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰
- 易于拓展 :增加新的具体建造者无需修改原有类库的代码,易于拓展,符合“开闭原则“。
建造者模式缺点:
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大
当生成的类比较复杂,并且生成的内部对象又相互依赖关系的情况下,可以选择建造者模式。