面试官:Builder模式是啥?给我说说

783 阅读4分钟

前言:今天本来准备写建造者模式的拓展,发现之前写的这篇建造者并没有发出来。现在发出来大家可以看看再回顾一遍建造者模式,看的同学也可以看我后面写的一篇建造者模式项目篇

模式动机

现实生活中,总是充满这复杂的对象,想汽车,电脑都是由多个组件组成的。抽象成类可以理解为汽车类有多个属性,可能为引用类型也可以为基础数据类型。创建一个这样的汽车对象往往需要复杂的操作,生成一个汽车对象然后根据不同的参数设置属性最终才能生成一辆汽车,有没有办法指定对象的类型后,可以直接创建一个需要的对象,这边是建造者模式的动机。


模式定义

造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。建造者模式属于对象创建型模式。根据中文翻译的不同,建造者模式又可以称为生成器模式。

模式结构

  • Builder:抽象建造者
  • ConcreteBuilder:具体建造者
  • Director:指挥者
  • Product:产品角色

UML图

时序图

示例代码

public abstract class Car {
    int A;
    int B;
    int C;


    @Override
    public String toString() {
        return "Car{" +
                "A=" + A +
                ", B=" + B +
                ", C=" + C +
                '}';
    }

    public int getA() {
        return A;
    }

    public void setA(int a) {
        A = a;
    }

    public int getB() {
        return B;
    }

    public void setB(int b) {
        B = b;
    }

    public int getC() {
        return C;
    }

    public void setC(int c) {
        C = c;
    }
}
public class RealCar extends Car{

}
public interface Builder {
    /**
     * 创建三个抽象方法代表 三个部分
     */
    public void addA(int i);
    public void addB(int i);
    public void addC(int i);
    Car createCar();
}
public class ConcreteBuilder implements Builder {
    Car car=new RealCar();

    @Override
    public void addA(int i) {
        car.setA(i);
    }

    @Override
    public void addB(int i) {
        car.setB(i);
    }

    @Override
    public void addC(int i) {
        car.setC(i);
    }

    @Override
    public Car createCar() {
        return car;
    }

}
public class Director {
    Builder builder;
    public Car createCar(int A,int B,int C){
        builder.addA(A);
        builder.addB(B);
        builder.addC(C);
        return builder.createCar();
    }

    public void setBuilder(Builder builder) {
        this.builder = builder;
    }
}
public class BuilderMain {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director();
        director.setBuilder(builder);
        Car car = director.createCar(1, 2, 3);
        System.out.println(car.toString());
    }
}

模式优点

  • 在建造者模式中, 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  • 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”。
  • 用户还可以使用不同构建者创建不同 的产品对象

模式缺点

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

总结

建造者模式跟工厂模式和装饰者模式都十分相似,自己学习的时候也很困惑,特别是当使用到构建器的时候,其中构建器的链式调用让我怀疑建造者和装饰者是同一个模式(如果不了解构建器的小伙伴可以 看我这篇),重新看了一遍装饰者的类图可以发现装饰模式实现的对多个对象的包装简单的说就是逐层包装,每次将生成的包装类作为一个另一个类中的参数不断延续下去,而构建器的链式调用,每次完成方法调用后,返回的是当前对象的this指针(即还是这个对象)。 工厂模式和建造者模式的区别则主要区别与抽象工厂模式相比, 建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族。