设计模式之建造者模式

建造者设计模式属于创建性模式,其目的在于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

适用场景:

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时
  • 创建一些复杂的对象时,这些对象的内部组成构件间的建造顺序是稳定的,但是对象的内部组成构件面临着复杂的变化

建造者模式角色说明:

  • Product:被构造的复杂对象
  • Director:调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建
  • Builder:抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建
  • ConcreteBuilder:实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例

建造者例子:

  比如建造一辆汽车,调用者不需要知道汽车(先生产引擎、轮胎、汽车框架等零件,再按一定顺序)是如何生产,只需要交给Director一个具体的建造者,就能生产出一辆相应的汽车,比如告诉Director,给我生产一辆奥迪,结果返回一辆奥迪给你。

  1、复杂的对象Product

/**
 * 
 * <p>
 * Car 建造者模式中的 复杂对象
 * <p>
 * 
 * @author <a href="mailto:yangkj@corp.21cn.com">yangkj</a>
 * @version
 * @since 2016年8月31日
 */
public class Car {
    
    // 汽车引擎
    private Enginer enginer;
    // 机车轮胎
    private Tyre tyre;
    // 汽车框架
    private CarFrame carFrame;
    
    public void Run(){
        System.out.println("汽车启动,开始跑了.....");
    }
    public Enginer getEnginer() {
        return enginer;
    }

    public void setEnginer(Enginer enginer) {
        this.enginer = enginer;
    }

    public Tyre getTyre() {
        return tyre;
    }

    public void setTyre(Tyre tyre) {
        this.tyre = tyre;
    }

    public CarFrame getCarFrame() {
        return carFrame;
    }

    public void setCarFrame(CarFrame carFrame) {
        this.carFrame = carFrame;
    }

}

class Enginer {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Enginer(String name) {
        this.name = name;
    }

}

class Tyre {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Tyre(String name) {
        this.name = name;
    }

}

class CarFrame {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public CarFrame(String name) {
        this.name = name;
    }

}
View Code

  2、Builder:

/**
 * 
 * <p>
 * Builder 抽象的建造者接口,定义要建造的汽车零件
 * <p>
 * 
 * @author <a href="mailto:yangkj@corp.21cn.com">yangkj</a>
 * @version
 * @since 2016年8月31日
 */
public interface Builder {
    
    public Enginer builderEnginer();

    public Tyre builderTyre();

    public CarFrame builderCarFrame();
}
View Code

  3、ConcreteBuilder

/**
 * 
 * <p>
 * AudiBuilder 继承Builder的奥迪汽车的建造者,负责创建具体的零件
 * <p>
 * 
 * @author <a href="mailto:yangkj@corp.21cn.com">yangkj</a>
 * @version
 * @since 2016年8月31日
 */
public class AudiBuilder implements Builder {

    public Enginer builderEnginer() {

        return new Enginer("奥迪牌引擎");
    }

    public Tyre builderTyre() {
        return new Tyre("奥迪牌轮胎");
    }

    public CarFrame builderCarFrame() {
        return new CarFrame("奥迪牌框架");
    }

}
View Code

  4、Director

/**
 * 
 * <p>
 * Director
 * 导演:调用传入的建造者,产生出相应的零件,再按一定的顺序组装(如果不同汽车组装顺序不同,我们可以再把Director抽象成接口,按照不同的汽车,
 * 再组装即可)
 * <p>
 * 
 * @author <a href="mailto:yangkj@corp.21cn.com">yangkj</a>
 * @version
 * @since 2016年8月31日
 */
public class Director {

    private Builder buider;

    // 构造方法中传入相应的建造者
    public Director(Builder buider) {
        this.buider = buider;
    }

    public Car directorCar() {
        // 生产汽车零件
        CarFrame carFrame = buider.builderCarFrame();
        Tyre tyre = buider.builderTyre();
        Enginer enginer = buider.builderEnginer();
        // 组装汽车
        Car audiCar = new Car();
        audiCar.setCarFrame(carFrame);
        audiCar.setTyre(tyre);
        audiCar.setEnginer(enginer);
        return audiCar;
    }
}
View Code

  5、客户端测试类

/**
 * 
 * <p>
 * Client 客户端
 * <p>
 * 
 * @author <a href="mailto:yangkj@corp.21cn.com">yangkj</a>
 * @version
 * @since 2016年8月31日
 */
public class Client {

    public static void main(String[] args) {

        // 交给Director一个奥迪建造者(AudiBuilder),建造出一辆奥迪车
        Director audiDirector = new Director(new AudiBuilder());

        Car audiCar = audiDirector.directorCar();

        System.out.println(audiCar.getCarFrame().getName());

        audiCar.Run();
    }
}
View Code

建造者好处:

  • 客户端不必知道产品具体的组成以及如何组装细节
  • 具体的建造者相互之间是独立的,符合OCP原则,利于横向扩展
posted @ 2016-08-31 10:35  星星满天  阅读(198)  评论(0编辑  收藏  举报