设计模式从入门到精通之(四)建造者模式

建造者模式:逐步构建复杂对象的艺术

在实际开发中,我们经常需要创建复杂对象,比如一份精美的菜单、一辆配置丰富的汽车,或者一套搭配完美的家居。而这些对象的构建往往需要分步骤进行,并且每一步都可能有不同的选择。

今天我们要聊的建造者模式,是一种优雅的方式,帮助我们一步步地构建这些复杂对象,同时保证代码的可读性和灵活性。


1. 什么是建造者模式?

建造者模式(Builder Pattern)是一种创建型设计模式,它将一个复杂对象的构造过程分解为多个步骤,让客户端可以按步骤逐步构建对象,而不用关心具体的实现细节。更重要的是,它可以让你自由地定制对象的每一部分。

用一句话总结:建造者模式将复杂对象的创建与其表示分离,使得同样的构建过程可以创建不同的表示。


2. 用现实中的故事引出建造者模式

想象你去定制一辆汽车。你可以选择不同的车身颜色、发动机类型、轮胎型号,还可以加装天窗、音响系统等附加配置。显然,这些配置的组合非常多,但整个定制过程可以分为以下几步:

  1. 确定基本车型(比如SUV、轿车)。
  2. 选择发动机(比如汽油、柴油或电动)。
  3. 选择轮胎(比如普通轮胎或防爆轮胎)。
  4. 添加额外配置(比如天窗、真皮座椅)。

最终,你会得到一辆完全符合你需求的汽车。

建造者模式正是这样的思想:将复杂对象的构建过程拆解为多个步骤,逐步完成每一步,最终构建出完整的对象。


3. 建造者模式的代码实现

下面我们以汽车定制为例,看看如何用建造者模式来构建一辆汽车。

3.1 汽车类

首先,我们定义一个表示汽车的类。

java 复制代码
class Car {
    private String type; // 汽车类型
    private String engine; // 发动机类型
    private String tires; // 轮胎类型
    private String features; // 附加配置

    public void setType(String type) {
        this.type = type;
    }

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

    public void setTires(String tires) {
        this.tires = tires;
    }

    public void setFeatures(String features) {
        this.features = features;
    }

    @Override
    public String toString() {
        return "Car [type=" + type + ", engine=" + engine + ", tires=" + tires + ", features=" + features + "]";
    }
}

3.2 建造者接口

定义一个建造者接口,规范汽车的构建步骤。

java 复制代码
interface CarBuilder {
    void buildType();
    void buildEngine();
    void buildTires();
    void buildFeatures();
    Car getResult();
}

3.3 具体建造者

实现具体的建造者类,分别构建不同类型的汽车。

java 复制代码
class SUVCarBuilder implements CarBuilder {
    private Car car = new Car();

    @Override
    public void buildType() {
        car.setType("SUV");
    }

    @Override
    public void buildEngine() {
        car.setEngine("Diesel Engine");
    }

    @Override
    public void buildTires() {
        car.setTires("All-Terrain Tires");
    }

    @Override
    public void buildFeatures() {
        car.setFeatures("Sunroof, Leather Seats");
    }

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

class SedanCarBuilder implements CarBuilder {
    private Car car = new Car();

    @Override
    public void buildType() {
        car.setType("Sedan");
    }

    @Override
    public void buildEngine() {
        car.setEngine("Petrol Engine");
    }

    @Override
    public void buildTires() {
        car.setTires("Standard Tires");
    }

    @Override
    public void buildFeatures() {
        car.setFeatures("Basic Audio System");
    }

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

3.4 指挥者

指挥者负责控制构建过程的顺序。

java 复制代码
class Director {
    private CarBuilder builder;

    public Director(CarBuilder builder) {
        this.builder = builder;
    }

    public Car construct() {
        builder.buildType();
        builder.buildEngine();
        builder.buildTires();
        builder.buildFeatures();
        return builder.getResult();
    }
}
3.5 客户端代码

客户端通过指挥者和具体建造者来构建汽车。

java 复制代码
public class Main {
    public static void main(String[] args) {
        // 构建SUV
        CarBuilder suvBuilder = new SUVCarBuilder();
        Director director1 = new Director(suvBuilder);
        Car suv = director1.construct();
        System.out.println(suv);

        // 构建轿车
        CarBuilder sedanBuilder = new SedanCarBuilder();
        Director director2 = new Director(sedanBuilder);
        Car sedan = director2.construct();
        System.out.println(sedan);
    }
}

运行结果:

复制代码
Car [type=SUV, engine=Diesel Engine, tires=All-Terrain Tires, features=Sunroof, Leather Seats]
Car [type=Sedan, engine=Petrol Engine, tires=Standard Tires, features=Basic Audio System]

4. 建造者模式的优缺点

优点:

  1. 步骤清晰:将复杂对象的创建过程拆解为多个步骤,代码清晰易读。
  2. 灵活性高:可以通过不同的建造者,构建不同表示的对象。
  3. 解耦:构造过程与最终表示相分离,便于维护。

缺点:

  1. 类的数量增加:每个具体建造者都需要单独定义一个类,增加了代码复杂性。
  2. 使用场景有限:适用于需要按步骤构建复杂对象的场景,对于简单对象可能显得过于复杂。

5. 总结

建造者模式是一种非常实用的设计模式,特别是在需要构建结构复杂、组件多样的对象时,可以显著提升代码的灵活性和可维护性。在实际开发中,我们可以灵活地结合建造者模式与其他模式,为复杂问题找到更优雅的解决方案。

下一篇专栏中,我们将深入探讨一种行为型模式:观察者模式,看看如何设计一个灵活的事件通知机制。


思考问题:

在建造者模式中,如果要支持更多类型的汽车(比如电动车),应该如何扩展现有代码?欢迎在评论区分享你的思路!

相关推荐
reddingtons1 小时前
【游戏宣发】PS “生成式扩展”流,30秒无损适配全渠道KV
游戏·设计模式·新媒体运营·prompt·aigc·教育电商·游戏美术
李慕婉学姐1 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆3 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin3 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20053 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉3 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国4 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882484 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈4 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_994 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc