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

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

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

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


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. 总结

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

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


思考问题:

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

相关推荐
xcl092511 分钟前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐2 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长2 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn2 小时前
Spring 注解使用详解
java·spring
一条小小yu2 小时前
Spring IoC的理解
java·后端·spring
落魄实习生3 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈3 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白4 小时前
核心功能(Service接口)
java·mybatis
乌暮5 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习