Java设计模式——建造者模式

建造者模式

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

何时使用:==一些基本部件不会变,而其组合经常变化的时候。==

如何解决:将变与不变分离开。

优点:

  1. 建造者独立,易扩展。
  2. 便于控制细节风险。

缺点:

​ 1. 产品必须有共同点,范围有限制。

​ 2. 如内部变化复杂,会有很多的建造类。

使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。而工厂更专注于零件的制造过程。

现在需要构建很多车辆,车的组成有车轮、外壳、发动机、方向盘等,每个组件有不同品牌,最后需要根据客户需求定制不同的车。(车的总体组成是一样的,组成部件变化)

/**
 * @author objcfeng
 * @description 车的实体类
 * @date 2020/11/2
 */
public class Car {
    //车轮
    private String wheel;
    //外壳
    private String shell;
    //发动机
    private String engine;
    //方向盘
    private String steeringWheel;

    @Override
    public String toString() {
        return "Car{" +
                "wheel='" + wheel + '\'' +
                ", Shell='" + shell + '\'' +
                ", engine='" + engine + '\'' +
                ", steeringWheel='" + steeringWheel + '\'' +
                '}';
    }

    public String getWheel() {
        return wheel;
    }

    public void setWheel(String wheel) {
        this.wheel = wheel;
    }

    public String getShell() {
        return shell;
    }

    public void setShell(String shell) {
        this.shell = shell;
    }

    public String getEngine() {
        return engine;
    }

    public void setEngine(String engine) {
        this.engine = engine;
    }

    public String getSteeringWheel() {
        return steeringWheel;
    }

    public void setSteeringWheel(String steeringWheel) {
        this.steeringWheel = steeringWheel;
    }
}
//车的建造者
public abstract class CarBuilder {
    //造车轮的方法,因为实际上车轮可能是一个复杂对象
    public abstract void buildWheel();
    //造外壳的方法
    public abstract void buildShell();
    //造引擎的方法
    public abstract void buildEngine();
    //造方向盘的方法
    public abstract void buildSteeringWheel();
    
    public abstract Car getCar();
}

建造者实现类,多个品牌组装不同的组件

/**
 * @author objcfeng
 * @description 奔驰建造者
 * @date 2020/11/2
 */
public class BenzBuilder extends CarBuilder {
    private Car car=new Car();

    @Override
    public void buildWheel() {
        car.setWheel("上好的车轮");
    }

    @Override
    public void buildShell() {
        car.setShell("奔驰外壳");
    }

    @Override
    public void buildEngine() {
        car.setEngine("奔驰产发动机");
    }

    @Override
    public void buildSteeringWheel() {
        car.setSteeringWheel("有奔驰标识的方向盘");
    }

    @Override
    public Car getCar() {
        return car;
    }
}
/**
 * @author objcfeng
 * @description 宝马建造者
 * @date 2020/11/2
 */
public class BmwBuilder extends CarBuilder {
    private Car car=new Car();

    @Override
    public void buildWheel() {
        car.setWheel("上好的车轮");
    }

    @Override
    public void buildShell() {
        car.setShell("宝马外壳");
    }

    @Override
    public void buildEngine() {
        car.setEngine("宝马产发动机");
    }

    @Override
    public void buildSteeringWheel() {
        car.setSteeringWheel("有宝马标识的方向盘");
    }

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

指挥者

/**
 * @author objcfeng
 * @description 指挥者,指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类
 * @date 2020/11/2
 */
public class CarDirector {
    private CarBuilder builder;

    public CarDirector(CarBuilder builder) {
        this.builder = builder;
    }
    public Car build(){
        builder.buildEngine();
        builder.buildShell();
        builder.buildSteeringWheel();
        builder.buildWheel();
        return builder.getCar();
    }
}

使用:

public class Main {
    public static void main(String[] args) {
        CarBuilder builder1=new BmwBuilder();
        CarBuilder builder2=new BenzBuilder();
        CarDirector carDirector = new CarDirector(builder1);
        Car car = carDirector.build();
        System.out.println(car);
    }
}

输出

Car{wheel='上好的车轮', Shell='宝马外壳', engine='宝马产发动机', steeringWheel='有宝马标识的方向盘'}

我们发现,在CarBuilder的实现类中,总是有个重写的getCar方法返回创建好的Car对象,并且CarBuilder的子类总是需要构建一个新的car对象。因为一个car对象只会被一个CarBuilder创建,因此,可以将car对象提升到CarBuilder抽象类中创建。如下,

//建造者
public abstract class CarBuilder {
    //新增创建一个新的car对象
    protected Car car = new Car();
     //其他方法不变
    public abstract void buildWheel();
    public abstract void buildShell();
    public abstract void buildEngine();
    public abstract void buildSteeringWheel();
    //修改返回car对象方法
    public Car getCar(){
        return this.car;
    };
}

实现类

/**
 * @author objcfeng
 * @description 宝马建造者
 * @date 2020/11/2
 */
public class BmwBuilder extends CarBuilder {
    //注意每个给car对象构建组成部分的方法调用的是父类的car对象
    @Override
    public void buildWheel() {
        super.car.setWheel("上好的车轮");
    }

    @Override
    public void buildShell() {
        super.car.setShell("宝马外壳");
    }

    @Override
    public void buildEngine() {
        super.car.setEngine("宝马产发动机");
    }

    @Override
    public void buildSteeringWheel() {
        super.car.setSteeringWheel("有宝马标识的方向盘");
    }
    
    //子类不需要实现getCar方法
    //    @Override
    //    public Car getCar() {
    //        return car;
    //    }
}

其他无需改变。

你可能感兴趣的:(java,设计模式,建造者模式)