设计模式-创建型之建造者模式

来源:互联网 发布:网站建设优化推广 编辑:程序博客网 时间:2024/05/19 01:06

模式动机

       在现实生活中,往往存在一些复杂的对象,它们有很多组成部分。比如一辆汽车,它包括很多个部件,如发动机、轮胎、外壳等等。而对于大部分用户而言,是不关心这些部件是如何装配、组装成一辆汽车的,他要的是一辆可使用的完整的汽车。如下图:
       这里写图片描述

模式定义

       在软件开发中,也存在类似的复杂对象,这个对象的属性就像汽车的部件,创建这个对象的过程就像组组装汽车的过程,由于过程复杂,整个过程往往被抽象到了一个称之为建造者的对象中,建造者返回给客户端的是一个已经组装完成的产品对象,客户端无须关心它们的建造过程和组装方式。建造者模式就是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,建造者模式也叫生成器模式

模式结构

这里写图片描述
       建造者模式主要由以下四部分组成:
  抽象建造者:抽象出建造复杂产品所需要的步骤,如Builder
  具体建造者:不同的具体建造者,各个步骤的具体实现,如CarBuilder
  指挥者:控制产品的生成过程,如控制各个步骤的先后顺序,组合方式等等,最终生成具体的产品,同时用于隔离客户端与产品建造过程,如Director
  具体产品:如Car

代码实现

  抽象建造者

public abstract class Builder {    public Car car = new Car();    public abstract void buildEngine();    public abstract void buildTyre();    public abstract void buildShell();    public Car getResult(){        return car;    }}

  具体建造者

public class CarBuilder extends Builder{    @Override    public void buildEngine() {        car.setEngine("我是发动机");    }    @Override    public void buildTyre() {        car.setTyre("我是轮胎");    }    @Override    public void buildShell() {        car.setShell("我是外壳");    }}

  指挥者

public class Director {    private Builder builder;    public Director(Builder builder){        this.builder = builder;    }    public void setBuilder(Builder builder){        this.builder = builder;    }    public Car construct(){        builder.buildEngine();        builder.buildTyre();        builder.buildShell();        return builder.getResult();    }}

  具体产品

public class Car {    private String engine;    private String tyre;    private String shell;    public String getEngine() {        return engine;    }    public void setEngine(String engine) {        this.engine = engine;    }    public String getTyre() {        return tyre;    }    public void setTyre(String tyre) {        this.tyre = tyre;    }    public String getShell() {        return shell;    }    public void setShell(String shell) {        this.shell = shell;    }}

  客户端测试类

public class Client {    public static void main(String[] args) {        Builder builder = new CarBuilder();        Director director = new Director(builder);        Car car = director.construct();        System.out.println(car.getEngine());        System.out.println(car.getTyre());        System.out.println(car.getShell());    }}

  运行客户端测试类,输出为

我是发动机我是轮胎我是外壳

模式简化

       在上面的示例代码中,为了简单起见,具体建造者只写了一个CarBuilder,但实际上具体建造者很有可能有多个,比如BMWCarBuilder,AudiCarBuilder,BenzCarBuilder,这也是为什么需要有一个抽象建造者的原因,它的作用就是把建造过程抽象出来,让具体的建造者去实现。所以,如果当我们的系统中确实只需要一个具体建造者时,那抽象建造者其实就没有存在的必要了,可以省去,同时指挥者也可以去掉了,直接在建造者中完成组装建造工作即可。

模式优缺点

优点

  • 降低了产品对象与产品对象创建过程的耦合度
  • 具体建造者相对独立,因此可以很方便的增加具体建造者或者替换某个具体建造者,客户端可以用不同的建造者得到不同的产品对象。比如用BMWCarBuilder得到BMWCar,用BenzCarBuilder得到BenzCar
  • 将创建步骤分解到各个方法中,使得创建过程更加清晰,能更好的控制产品的创建过程

缺点

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

适用场景

  • 需要生成的产品对象内部结构复杂,包含多个属性,这些属性相互依赖,甚至需要按指定顺序生成
  • 对象的创建过程独立于创建该对象的类,建造者模式中,建造的具体过程是封装在指挥者类中,而不在建造者类中
  • 隔离复杂对象的创建和使用,使得相同的创建过程可以得到不同的产品

总结

       建造者模式的精髓在于“建造”二字,在前面的抽象工厂模式中,该模式是返回一系列的产品,这些产品位于不同的产品等级结构,构成一个产品族。而建造者模式侧重于“组装”复杂对象的这个过程,返回的是一个完整的产品对象。如果将抽象工厂模式看作汽车部件生产工厂,生产一个产品族的产品,那建造者模式就是一个汽车组装工厂,通过组装各个部件,返回一辆完整的汽车。

0 0