设计模式之建造者模式

建造者模式(Builder Pattern)是一种对象创建型设计模式,它旨在找到一种灵活构建复杂对象的方式。

一、概述

在建造者模式中,一个复杂对象的表示与它的构造过程分离,使得同样的构建过程可以创建不同的表示。建造者模式通常包含以下几个角色:

1、产品(Product)角色

它是被构建的复杂对象,包含多个组成部件的类(如汽车的轮胎、发动机等)。

2、抽象建造者(Builder)角色

定义一个接口,用于规范产品对象的各个组成部分的建造。一般而言,这个接口中定义了产品的创建方法和返回方法。

3、具体建造者(ConcreteBuilder)角色

实现Builder接口,完成复杂产品的具体创建。在构建过程完成后,提供产品的实例。

4、指挥者(Director)角色

负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其construct()建造方法中调用建造者对象的部件构造和装配方法,完成复杂对象的创建。客户端一般只需要与指挥者进行交互,以建造出复杂的产品对象。

二、建造者模式的优点

1、封装性好:

使用建造者模式可以使客户端不必知道产品内部组成的细节。

2、扩展性好:

建造者模式易于扩展,增加新的具体建造者无须修改原有类库的代码,易于遵守开闭原则。

3、便于控制细节:

如果产品类非常复杂,或者产品类中的调用顺序不同会产生不同的作用,那么使用建造者模式就非常合适,因为具体的建造者类可以对这些细节进行很好的封装。

三、建造者模式的缺点

1、产生多余的Builder对象:

由于建造者模式中的具体建造者通常是独立的,因此其创建的过程中不可避免会产生一些只包含临时数据的对象,如果建造者模式使用不当,会造成资源的浪费。

2、设计难度增加:

建造者模式的加入会使系统中类的个数增加,在一定程度上增加了系统的理解与设计难度。

四、Java代码示例

以下是一个使用建造者模式构建汽车的示例。在这个例子中,我们有一个Car类作为产品,一个CarBuilder接口作为抽象建造者,几个具体的CarBuilder实现类(如SedanBuilder、SUVBuilder等),以及一个CarDirector类作为指挥者。

1. 定义产品类(Car)

java 复制代码
public class Car {  
    private String engine;  
    private String body;  
    private String wheels;  
  
    // 省略构造方法  
  
    // Getter 和 Setter  
    public String getEngine() {  
        return engine;  
    }  
  
    public void setEngine(String engine) {  
        this.engine = engine;  
    }  
  
    public String getBody() {  
        return body;  
    }  
  
    public void setBody(String body) {  
        this.body = body;  
    }  
  
    public String getWheels() {  
        return wheels;  
    }  
  
    public void setWheels(String wheels) {  
        this.wheels = wheels;  
    }  
  
    // 显示汽车信息  
    public void display() {  
        System.out.println("Engine: " + engine);  
        System.out.println("Body: " + body);  
        System.out.println("Wheels: " + wheels);  
    }  
}

2. 定义抽象建造者(CarBuilder)

java 复制代码
public interface CarBuilder {  
    void buildEngine();  
    void buildBody();  
    void buildWheels();  
  
    // 返回最终构建的汽车产品  
    Car getCar();  
}

3. 定义具体建造者(SedanBuilder 和 SUVBuilder)

java 复制代码
public class SedanBuilder implements CarBuilder {  
    private Car car = new Car();  
  
    @Override  
    public void buildEngine() {  
        car.setEngine("V6 Engine");  
    }  
  
    @Override  
    public void buildBody() {  
        car.setBody("Sedan Body");  
    }  
  
    @Override  
    public void buildWheels() {  
        car.setWheels("4 Wheels");  
    }  
  
    @Override  
    public Car getCar() {  
        return car;  
    }  
}  
  
public class SUVBuilder implements CarBuilder {  
    private Car car = new Car();  
  
    @Override  
    public void buildEngine() {  
        car.setEngine("V8 Engine");  
    }  
  
    @Override  
    public void buildBody() {  
        car.setBody("SUV Body");  
    }  
  
    @Override  
    public void buildWheels() {  
        car.setWheels("4 Wheels with All-Wheel Drive");  
    }  
  
    @Override  
    public Car getCar() {  
        return car;  
    }  
}

4. 定义指挥者(CarDirector)

java 复制代码
public class CarDirector {  
    private CarBuilder builder;  
  
    public CarDirector(CarBuilder builder) {  
        this.builder = builder;  
    }  
  
    // 构造顺序  
    public Car constructCar() {  
        builder.buildEngine();  
        builder.buildBody();  
        builder.buildWheels();  
        return builder.getCar();  
    }  
}

5. 客户端代码

java 复制代码
public class Client {  
    public static void main(String[] args) {  
        // 使用 SedanBuilder  
        CarBuilder sedanBuilder = new SedanBuilder();  
        CarDirector director = new CarDirector(sedanBuilder);  
        Car sedan = director.constructCar();  
        sedan.display();  
  
        // 使用 SUVBuilder  
        CarBuilder suvBuilder = new SUVBuilder();  
        director = new CarDirector(suvBuilder);  
        Car suv = director.constructCar();  
        suv.display();  
    }  
}

6、深入解析

在上面的例子中,Car类是一个复杂的产品,包含发动机、车身和轮子等部分。CarBuilder接口定义了如何构建这些部分,而SedanBuilder和SUVBuilder是具体的建造者,分别实现了不同的构建逻辑。CarDirector类则负责按照特定的顺序调用建造者的方法,以构建出完整的汽车对象。

客户端代码通过创建不同的建造者实例,并将其传递给指挥者,来构建不同类型的汽车。这种方式使得客户端与产品的具体构建过程解耦,客户端只需要知道指挥者和建造者的接口,而不需要知道具体的实现细节。

7、建造者模式的变体

在实际应用中,建造者模式有时会有一些变体。例如,有些情况下可能不需要指挥者角色,而是直接在客户端代码中调用建造者的方法来构建产品。此外,还可以将建造者模式与其他设计模式结合使用,如工厂模式、单例模式等,以实现更复杂的系统设计。

五、总结

建造者模式是一种强大的设计模式,它允许我们通过组合不同的组件来构建复杂对象,同时保持构建过程的灵活性和可扩展性。通过定义抽象建造者接口和具体建造者实现类,我们可以将产品的构建过程与产品的表示分离,从而实现更好的封装和复用。此外,建造者模式还提供了很好的扩展性,使得我们可以在不修改原有代码的情况下添加新的具体建造者类来构建新的产品。

相关推荐
阿伟*rui4 分钟前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck2 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei2 小时前
java的类加载机制的学习
java·学习
Yaml44 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~4 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616884 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7895 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java5 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~5 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust