23种设计模式之建造者模式

  • 2019 年 10 月 4 日
  • 笔记

1

/ 写在前面的话 /

首先,我先举几个生活的场景来描述一下建造者模式。比如一个手机,它是有许多复杂的零件组成,当我们组装这些零件的时候是不是会有一个步骤问题?在实际的开发中,我们所需要的对象构建时,也是非常的复杂,有很多的步骤需要我们去处理。

我们再来说说建造模式的本质:

– 分离了对象子组件的单独构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况下使用。

– 由于实现了构建和装配的解耦。不同的构建器,相同的装配,也可以做出不同的对象;相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算法的解耦,实现了更好的复用。

2

/建造者模式/

  1. 首先我们来模拟一台车辆的建造,我就拿车的引擎和轮胎来说说吧!我们先创建三个类分别是Car , Engine, Tyre 。为了防止创建太多的文件,我就直接写在一个java文件中。
package com.kuls.builder;    public class Car {     private Tyre tyre;     private Engine engine;       public void lanch(){           System.out.println("出发!!!");       }      public Tyre getTyre() {          return tyre;      }        public void setTyre(Tyre tyre) {          this.tyre = tyre;      }        public Engine getEngine() {          return engine;      }        public void setEngine(Engine engine) {          this.engine = engine;      }  }    /***   * 轮胎   */  class Tyre{      public Tyre() {      }        public Tyre(String name) {          this.name = name;      }        private String name;        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }  }    /***   * 引擎   */  class Engine{      public Engine(String name) {          this.name = name;      }        private String name;        public Engine() {        }        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }  }

可以看到我们在Car类中定义了Engine和Tyre类,并且提供了set,get方法,我们还写了一个lanch方法。这里的get/set方法是为了得到Car对象中的Engine,Tyre。

2.因为我们要将创建车和组装车两个步骤分开,我们可以分别定义创建车和组装车的接口来实现

public interface CarBuilder {      Engine builderEngine();      Tyre builderTyre();  }
public interface CarDirector {      Car directorCar();  }

在CarBuilder接口中我们定义了创建引擎,创建轮胎两个方法接口,在CarDirector中定义了一个组装车的接口并且返回值是一个Car对象

我们的物品(轮胎,引擎)和创建者,组装者都已经弄好了,现在就可以来组装一台属于我们的车了,我把这台车命名为ITCar。

3.首先来写一下 ITCarBuilder

public class ITCarBuilder implements CarBuilder{        @Override      public Engine builderEngine() {          return new Engine("IT资源君版引擎");      }        @Override      public Tyre builderTyre() {          return new Tyre("IT资源君版轮胎");      }  }

可以看到我们是继承了CarBuilder的接口,这就是我们为啥要去写CarBuilder接口。然后我们重写接口中的方法,此时就可以自定义我们的引擎和轮胎了

4.轮胎和引擎创建好后,然后就是来组装一下我们的车了

public class ITCarDirector implements CarDirector {      private ITCarBuilder itCarBuilder;        public ITCarDirector(ITCarBuilder itCarBuilder) {          this.itCarBuilder = itCarBuilder;      }        @Override      public Car directorCar() {         Engine e = itCarBuilder.builderEngine();         Tyre t =itCarBuilder.builderTyre();         Car car = new Car();         car.setEngine(e);         car.setTyre(t);          return car;      }  }

我们首先创建一个带参构造器,参数是一个ITCarBuilder对象,传入这个参数就是要把创建好的引擎和轮胎传入组装间进行组装。在directorCar方法中,我们通过itCarBuilder对象来创建引擎和轮胎,然后创建一个Car对象,并把创建好的引擎和轮胎安装在这辆车中,然后把这辆车返回。

5.万事俱备,只欠调用了

public class Test {      public static void main(String[] args){        ITCarDirector itCarDirector = new ITCarDirector(new ITCarBuilder());        Car car = itCarDirector.directorCar();          System.out.println(car.getEngine().getName());          System.out.println(car.getTyre().getName());          car.lanch();      }  }

运行结果:

IT资源君版引擎  IT资源君版轮胎  出发!!!

可以看到我们将建造者和组装者分离之后创建出的IT版Car

3

/ end /

在我们实际开发中,其实碰到了许多的建造者模式,比如:

– StringBuilder类的append方法

– SQL中的PreparedStatement

– JDOM中,DomBuilder、SAXBuild

若有错误,请在后台留言!