生成器模式是什么?

生成器模式

概述

把创建对象的步骤抽象成了生成器,通过指导类(director)控制对象生成的步骤顺序进行。

感觉是否和工厂模式类似?但侧重点不同,生成器的重点在于对于生成对象的步骤细化,有些步骤如果不需要或者生产次序需要改变,指导类就可以对生成对象步骤进行取舍或改变次序。而工厂类做不到这点,需要修改大量代码甚至创建新的抽象工厂。简言之,工厂针对系列产品,生成器针对一个产品所拥有的属性强弱(复杂或简单)。

工厂创建对象后会立即返回对象,生成器允许在获取对象前再执行额外的操作。

举一个汽车生产的例子,拿豪华Bat Man战车和普通Bat Man战车为例:

战车有一系列产品属性:Engine、Frame、Material、Wheel等

  • 产品特征类
public class Engine {
    private double volume;//体积
    private double mileage;//提速指标(每小时提速)
    
    //....构造方法、set/get方法 省略
}

public class Frame {
    private boolean isPipeLine;//流水型
    private boolean isChangable;//顺应环境可变化
    
    //....构造方法、set/get方法 省略
}

public enum Material {
    UNIVERSE_ALLOY/*宇宙合金*/, ALLOY/*稀有合金*/, ORDINARY_IRON/*普通钢铁*/
}

public enum Wheel {
    ORDINARY_WHEEL/*普通轮*/, LUXURY_WHEEL/*豪华轮*/
}

  • 战车类
public class BatCar {
    private String engine;
    private String frame;
    private String material;
    private String wheel;
	
    //.......构造方法、set/get方法省略
}
  • 通用设计战车生成器接口
public interface CarBuilder {
    void setEngine(String engine);//配置引擎
    void setFrame(String frame);//设计架构
    void setMaterial(String material);//设置车身材料
    void setWheel(String wheel);//车轮设计
    //.....other code
}
  • 战车生成器类
public class BatCarBuilder implements CarBuilder {
    private String engine;
    private String frame;
    private String material;
    private String wheel;
    
    @Override
    void setEngine(String engine) {
    	this.engine = engine;
    }
    @Override
    void setFrame(String frame) {
        this.engine = engine;
    }
    @Override
    void setMaterial(String material) {
        this.material = material;
    }
    @Override
    void setWheel(String wheel) {
        this.wheel = wheel;
    }
    
    public BatCar getResult() {
        return new BatCar(engine, frame, material, wheel);
    }
}
  • 指导类
public class BatCarDirector {//此处指导类可采取单例模式
    void prdOrdinaryCar(CarBuilder builder) {//生成普通战车
        builder.setEngine(new Engine(3.0, 3.0));
        builder.setFrame(new Frame(true, false));
        builder.setMaterial(Material.ORDINARY_IRON);
        builder.setWheel(Wheel.ORDINARY_WHEEL);
    }
    
    void prdLuxuryCar(CarBuilder builder) {//生成豪华战车
        builder.setEngine(new Engine(3.0, 10.0));
        builder.setFrame(new Frame(true, true));
        builder.setMaterial(Material.UNIVERSE_ALLOY);
        builder.setWheel(Wheel.LUXURY_WHEEL);
    }
}
  • 客户端代码
public class Demo {
    public static void main(String[] args) {
        BatCarDirector director = new BatCarDirector();
     	BatCarBuilder builder = new BarCarBuilder();
        director.prdOrdinaryCar(builder);//指导生成器生成普通战车car
        BatCar bat_car = builder.getResult();//从生成器中获取实例对象
        
        director.prdLuxuryCar(builder);//指导生成器生成豪华战车car
        BatCar bat_car = builder.getResult();//从生成器中获取实例对象
    }
}

依照此同理可知,换个对象,比如蝙蝠战车的详细指南手册,也可使用生成器模式,生成同一系列不同指标的产品

优点:

  • 适用于复杂对象的创建,避免重叠复杂构造函数的出现
  • 分步骤创建对象,可递归运行创建步骤
  • 复用相同的构建代码
  • 符合单一职责

缺点:

  • 代码复杂
posted @ 2020-09-12 20:36  Faink  阅读(371)  评论(0)    收藏  举报