设计模式之建造者模式

 

概述

建造者模式构建复杂对象就像造汽车一样,一个一个组件一个一个步骤创建出来,它允许指定的组件对象和内容来创建,用户无需知道复杂对象如何创建,只需要明白通过这样方式可以得到复杂对象的实例。

定义

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的显示。

建造者角色

Builder

抽象建造者。它声明为创建一个Product对象的各个部件指定的抽象接口。

ConcreteBuilder

具体建造者。实现抽象接口,构建和装配各个部件。

Director

指挥者。构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。

1、隔离了客户与对象的生产过程。2、负责控制产品对象的生产过程。

Product

产品角色。

一个具体的产品对象。

类图

经典例子

Product 产品类

public class Product {

    List<String> parts = new ArrayList<String>();
    // 添加产品部件
    public void add(String part) {
        parts.add(part);
    }
    // 查询产品部件
    public void show() {
        for (String part: parts) {
            System.out.println(part);
        }
    }

}

 Builder 抽象建造者

public interface Builder {

    void buildPartA();

    void buildPartB();

    Product getResult();

}

具体建造者A、B

public class ConcreteBuilderA implements  Builder {

    private Product product = new Product();
    @Override
    public void buildPartA() {
        product.add("部件A");
    }

    @Override
    public void buildPartB() {
        product.add("部件B");
    }

    @Override
    public Product getResult() {
        return product;
    }
}
public class ConcreteBuilderB implements  Builder {

    private Product product = new Product();
    @Override
    public void buildPartA() {
        product.add("部件X");
    }

    @Override
    public void buildPartB() {
        product.add("部件Y");
    }

    @Override
    public Product getResult() {
        return product;
    }
}

指挥者类

public class Director {

    public void construct(Builder builder) {
        builder.buildPartA();
        builder.buildPartB();
    }
}

测试类

public class Test {


    public static void main(String[] args) {
        Director director = new Director();
        Builder builderA = new ConcreteBuilderA();
        Builder builderB = new ConcreteBuilderB();

        director.construct(builderA);

        Product p1 = builderA.getResult();
        p1.show();


        director.construct(builderB);

        Product p2 = builderB.getResult();
        p2.show();
    }
}

测试结果

部件A
部件B
部件X
部件Y

如果上面代码不是很好理解,接下里我们来写情景代码,通过情景代码更好的理解建造者模式。

情景代码

我们用制造自行车为例子讲解建造者模式,自行车由车架、轮胎、脚踏等部件组成,如下图所示。自行车制造公司就是把这些零部件组装起来 。

                                           

 

 

自行车制造公司的工程部门相当于指挥者,生产部门相当于建造者,当今共享单车做的比较大的摩拜和ofo相当于客户,单车就是产品了。

单车对象

public class Bike {

    // 轮胎
    private String tyre;
    // 车架
    private String frame;
    // GPS定位装置
    private String gps;

    // 省略set()get()方法

}

 创建者接口

public interface BikeBuilder {
    // 组装轮胎
    public void buildTyres();
    // 组装车架
    public void buildFrame();
    // 组装GPS定位装置
    public void buildGPS();
    // 获取自行车
    public Bike getBike();
}

 摩拜单车生产线

public class MoBikeBuilder implements  BikeBuilder {

    // 单车对象
    Bike bike = new Bike();

    @Override
    public void buildTyres() {
        bike.setTyre("橙色轮胎");
    }

    @Override
    public void buildFrame() {
        bike.setFrame("橙色车架");
    }

    @Override
    public void buildGPS() {
        bike.setGps("mobike定制版GPS定位装置");
    }

    @Override
    public Bike getBike() {
        return bike;
    }
}

  OFO单车生产线

public class OfoBikeBuilder implements  BikeBuilder  {
    // 单车对象
    Bike bike = new Bike();

    @Override
    public void buildTyres() {
        bike.setTyre("黑色轮胎");
    }

    @Override
    public void buildFrame() {
        bike.setFrame("黄色车架");
    }

    @Override
    public void buildGPS() {
        bike.setGps("ofo定制版GPS定位装置");
    }

    @Override
    public Bike getBike() {
        return bike;
    }
}

 工程部

public class EngineeringDepartment {

    // 用户告知指挥者想要什么样的单车
    BikeBuilder bikeBuilder;

    public EngineeringDepartment(BikeBuilder bikeBuilder){
        this.bikeBuilder = bikeBuilder;
    }

    // 指导组装单车
    public void Construct(){
        bikeBuilder.buildTyres();
        bikeBuilder.buildFrame();
        bikeBuilder.buildGPS();
    }
}

  测试类

public static void main(String[] args) {
        // 建造摩拜单车
        BikeBuilder moBikeBuilder = new MoBikeBuilder();
        EngineeringDepartment ed1 = new EngineeringDepartment(moBikeBuilder);
        ed1.Construct();// 指导组装
        // 产出单车,体现建造和显示分离
        Bike moBike = moBikeBuilder.getBike();
        System.out.println(moBike.getFrame()+"   "+moBike.getTyre()+"   "+moBike.getGps());

        // 建造ofo单车
        BikeBuilder ofoBikeBuilder = new OfoBikeBuilder();
        EngineeringDepartment ed2 = new EngineeringDepartment(ofoBikeBuilder);
        ed2.Construct();// 指导组装
        Bike ofoBike = ofoBikeBuilder.getBike();
        System.out.println(ofoBike.getFrame()+"   "+ofoBike.getTyre()+"   "+ofoBike.getGps());

    }

测试结果

橙色车架   橙色轮胎   mobike定制版GPS定位装置
黄色车架   黑色轮胎   ofo定制版GPS定位装置

建造者模式的优缺点

优点

(1)产品的建造和表示分离,实现了解耦。

(2)隐藏了产品的建造细节,用户只需关心产品的表示,而不需要了解是如何创建产品的。

(3)体现了开闭原则,如上代码所示,如果需要再生产其他共享单车,只需要再开一条生产线即可,不影响其他生产线的作业。

缺点

(1)建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。       

(2)如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

使用场景

1、需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。

2、隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

总结

建造者模式的使用场合是当创建复杂对象时,把创建对象成员和装配方法分离出来,放在建造者类中去实现,用户使用该复杂对象时,不用理会它的创建和装配过程,只关心它的表示形式。其实完全理解这个模式还是要一番思考的,难以搞懂的是指挥者似乎没什么存在的必要,在代码里也没体现它的作用,我们也可以把指挥者的方法放在建造者里面,但为什么没有这样做呢?我想这可能是考虑到单一责任原则,建造者只负责创建对象的各个部分,至于各个部分创建的顺序、装配方法它就不管了。还有就是当顺序要改变时,建造者可以不用改动,改动指挥者就好了,指挥者只有一个,建造者有很多,要改建造者就麻烦了。

 

源码地址:

https://github.com/xiaonongOne/builder_pattern

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值