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

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


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

上一篇:thinkPHP5 图像上传线上 failed to open stream: Permission denied 问题


下一篇:mysql5.7中SELECT command denied to user