设计模式之建造者模式(创建型模式)

116 阅读5分钟

建造者模式的概念

  • 使用多个简单的对象,通过指定的顺序来一步步构建出一个复杂的对象.
  • 用户并不需要知道内部是如何构建的,直接就可以创建出复杂的对象.

代码实现

建造者模式中有四个角色

  • 抽象建造者(builder):描述具体的建造者的接口,只是用来定义建造的方法,不需要实现具体的细节.
  • 具体建造者(ConcreteBuilder):实现抽象建造者的接口,并具体化建造过程.
  • 指挥者(Director):调用具体的建造者,按照指定的顺序一步步构造出复杂饿对象(产品).
  • 产品(Product):一个由各种简单对象组成的复杂对象.

代码实现

产品类-Hamburg 类

public class Hamburg {
    private String Bread;
    private String Sauce;
    private String Lettuce;
    private String Chick;

    public String getBread() {
        return Bread;
    }

    public void setBread(String bread) {
        Bread = bread;
    }

    public String getSauce() {
        return Sauce;
    }

    public void setSauce(String sauce) {
        Sauce = sauce;
    }

    public String getLettuce() {
        return Lettuce;
    }

    public void setLettuce(String lettuce) {
        Lettuce = lettuce;
    }

    public String getChick() {
        return Chick;
    }

    public void setChick(String chick) {
        Chick = chick;
    }

    @Override
    public String toString() {
        return "Hamburg{" +
                "Bread='" + Bread + ''' +
                ", Sauce='" + Sauce + ''' +
                ", Lettuce='" + Lettuce + ''' +
                ", Chick='" + Chick + ''' +
                '}';
    }
}

抽象建造者-Builder类

public abstract class Builder {
   public abstract void openBread();
   public abstract void smearSauce();
   public abstract void putLettuce();
   public abstract void putChick();
   public abstract Hamburg createHamburg();
}

具体的建造者-HamburgBuilder类

public class HamburgBuilder extends Builder{

    private Hamburg hamburg;
    public HamburgBuilder(){
        hamburg = new Hamburg();
    }

    @Override
    public void openBread() {
        hamburg.setBread("大面包");
    }

    @Override
    public void smearSauce() {
        hamburg.setSauce("辣酱");
    }

    @Override
    public void putLettuce() {
      hamburg.setLettuce("生菜");
    }
    @Override
    public void putChick() {
        hamburg.setChick("辣鸡肉");
    }
    @Override
    public Hamburg createHamburg() {
        return hamburg;
    }
}

指挥类-Director类

public class Director {

    public Hamburg makeHambury(Builder builder){
        builder.openBread();
        builder.smearSauce();
        builder.putLettuce();
        builder.putChick();
        return builder.createHamburg();
    }
}

测试类

public static void main(String[] args) throws CloneNotSupportedException {
    Director director = new Director();
    Hamburg hamburg = director.makeHambury(new HamburgBuilder());
    System.out.println(hamburg);
}

执行结果

Hamburg{Bread='大面包', Sauce='辣酱', Lettuce='生菜', Chick='辣鸡肉'}

这样就组成了一个建造者模式.

扩展建造者模式

看了以上代码,感觉建造者模式好像并没有什么很大的作用,只是让代码看起来更加复杂,下面有一种更加常用的方式组建构造者模式

代码实现

Hamburg 类

public class Hamburg {
    private String bread;
    private String sauce;
    private String lettuce;
    private String chick;

    private Hamburg(Builder builder){
        this.bread = builder.bread;
        this.sauce = builder.sauce;
        this.lettuce = builder.lettuce;
        this.chick = builder.chick;
    }

    public static final class Builder{
        private String bread;
        private String sauce;
        private String lettuce;
        private String chick;

        public Builder setBread(String bread) {
            this.bread = bread;
            return this;
        }

        public Builder setSauce(String sauce) {
            this.sauce = sauce;
            return this;
        }

        public Builder setLettuce(String lettuce) {
            this.lettuce = lettuce;
            return this;
        }

        public Builder setChick(String chick) {
            this.chick = chick;
            return this;
        }
        public Hamburg createHamburg(){
            return new Hamburg(this);
        }
    }

    public String getBread() {
        return bread;
    }

    public void setBread(String bread) {
        this.bread = bread;
    }

    public String getSauce() {
        return sauce;
    }

    public void setSauce(String sauce) {
        this.sauce = sauce;
    }

    public String getLettuce() {
        return lettuce;
    }

    public void setLettuce(String lettuce) {
        this.lettuce = lettuce;
    }

    public String getChick() {
        return chick;
    }

    public void setChick(String chick) {
        this.chick = chick;
    }

    @Override
    public String toString() {
        return "Hamburg{" +
                "bread='" + bread + ''' +
                ", sauce='" + sauce + ''' +
                ", lettuce='" + lettuce + ''' +
                ", chick='" + chick + ''' +
                '}';
    }
}

测试类

public static void main(String[] args) throws CloneNotSupportedException {
    Hamburg hamburg = new Hamburg.Builder().setBread("小面包").setLettuce("苹果酱").setChick("鸡腿").createHamburg();
    System.out.println(hamburg);
}
Hamburg{bread='小面包', sauce='null', lettuce='苹果酱', chick='鸡腿'}

这种方式是比较常用的建造者使用方式,他通过链式清晰明了的将对象构建出来. 其实在 lombok 中也 提供了 @Builder @SpuerBuilder这两个注解来实现上面的功能.

建造者模式的优缺点以及应用场景

优点

  • 产品的建造和表示分离,实现了解耦。
  • 将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰
  • 增加新的具体建造者无需修改原有类库的代码,易于拓展,符合“开闭原则“

缺点

  • 产品必须有共同点,限制了使用范围
  • 如内部变化复杂,会有很多的建造类,难以维护

应用场景

  • 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性
  • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品
  • 适合于一个具有较多的零件(属性)的产品(对象)的创建过程

建造者模式与工厂方法模式和抽象工厂模式的区别

建造者模式与工厂方法模式的区别

  • 工厂方法模式注重的是整体对象的创建方式;
  • 建造者模式注重的是部件构造的过程,意在一步步创建出符合自己需求的对象.
  • 举例:我想吃一道菜,工厂方法模式就类似于预制菜,他的炒制过程以及食材都是一样的,我只需要加热就可以直接吃了;建造者模式就像是我自己一步一步的制作出这道菜,可以随自己的爱好选择步骤以及食材的不同.
  • 工厂方法模式就是批量生产,建造者模式就是定制生产.

建造者模式与抽象工厂模式的区别

  • 抽象工厂模式实现的是同一种类对象创建,但是属于不同维度的对象,他不需要关心构建过程,只要知道什么对象由什么对象的工厂生产即可.
  • 建造者模式是按照指定的要求来生产,他的目的就是通过组装配件生产一个新的产品.
  • 举例:抽象工厂模式就像汽车的配件生产工厂,指定的配件肯定是指定的工厂才可以生产;建造者模式就像是汽车的组装工厂,由各个零件组装成一辆完整的汽车,但是也可以通过修改不同的配件生产出另一辆全新的汽车