好记忆不如烂笔头,能记下点东西,就记下点,有时间拿出来看看,也会发觉不一样的感受.

本文还是将从:建造者模式的前世今生;使用场景;注意事项;代码样例等四个方面,详细阐述下建造者模式的细节内容。

Java 建造者模式

  • 前世今生
    • 发展历程 :在 Java 社区早期,当对象构造逻辑较为复杂时,开发人员常常会遇到构造函数参数过多、参数顺序易错等问题,这促使大家去寻找更好的解决方案。建造者模式应运而生后,逐渐被广泛采用,尤其是在需要构建复杂对象、对象层次深或者对象参数众多的场景中,如构建图形界面中的复杂组件、生成各种请求对象等。

    • 起源 :建造者模式(Builder Pattern)属于创建型设计模式。在软件开发过程中,随着项目的发展,对象的创建逻辑可能会变得复杂,比如一个对象需要多个参数来构建,并且这些参数有些是必须的,有些是可选的。传统的方法如使用构造函数或工厂方法来创建对象可能会导致代码难以维护和扩展。1994 年,设计模式经典著作《Design Patterns: Elements of Reusable Object-Oriented Software》(通常简称 “Gang of Four” 或 “GoF” 书)正式提出建造者模式,旨在解决这一类问题,将复杂的对象构建过程分离出来,以便于更灵活地创建对象。

    • 使用场景

      • 复杂对象创建 :当要创建的对象有多个属性,其中包含可选属性和必需属性,并且对象的构建过程较为复杂时,例如创建一份简历,简历包含姓名、性别、工作经历、项目经验等诸多信息,其中姓名、性别是必需的,而工作经历、项目经验等可选。使用建造者模式可以清晰地逐步构建这份简历对象,先设置必需的姓名和性别,再根据需要添加可选的其他信息。

      • 对象不可变性需求 :当希望创建不可变对象(即对象一旦创建后,其属性就不能再修改),但又需要在创建时灵活地设置多个属性值时,建造者模式很有用。因为不可变对象的传统构造方式(如构造函数参数多、容易出错)存在问题,而建造者模式可以让开发者以更安全、清晰的方式构建不可变对象,如构建一个不可变的日期时间对象。

      • 分步骤创建对象 :在一些场景下,对象的创建需要分多个步骤进行,比如创建一个游戏中的角色,需要先设定角色的基本属性(如名字、等级),然后选择装备,再设置技能等。这时候建造者模式可以对每个步骤进行封装,让用户能够清晰地按照步骤去创建完整的游戏角色对象。

    • 使用的注意事项

      • 性能方面 :建造者模式在一定程度上可能会增加代码的运行时开销。因为涉及到多个对象(如建造者对象、导演者对象等)以及更多的方法调用来逐步构建对象,相比直接使用构造函数创建对象来说,性能可能会稍有下降。所以在对性能要求极高的场景下,如在嵌入式系统中需要频繁创建大量简单对象时,需要谨慎使用建造者模式,或者对其进行适当的优化。

      • 代码复杂度管理 :虽然建造者模式可以让对象的创建过程更灵活,但也会引入更多的代码(如建造者类、导演者类等),这就增加了代码的复杂度。如果项目中对象的创建过程比较简单,没有必要使用建造者模式,否则会使项目变得臃肿,难以维护。只有在对象创建确实复杂到需要清晰构建流程时,才考虑采用此模式。

      • 过度使用问题 :避免在不适合的场景下过度使用建造者模式。例如,当对象的属性很少,并且创建逻辑简单时,使用简单的构造函数或工厂方法可能更合适。不要盲目追求设计模式的使用,而忽略了实际问题的简单性。

    • 代码样例

      • 产品类(Product) :即要创建的复杂对象,通常包含多个属性。

public class Computer {
    private String cpu;
    private String memory;
    private String disk;
    private String graphicsCard;

    // 私有化构造函数,防止直接通过构造函数创建对象
    private Computer(ComputerBuilder builder) {
        this.cpu = builder.cpu;
        this.memory = builder.memory;
        this.disk = builder.disk;
        this.graphicsCard = builder.graphicsCard;
    }

    // getter 方法
    public String getCpu() {
        return cpu;
    }

    public String getMemory() {
        return memory;
    }

    public String getDisk() {
        return disk;
    }

    public String getGraphicsCard() {
        return graphicsCard;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", disk='" + disk + '\'' +
                ", graphicsCard='" + graphicsCard + '\'' +
                '}';
    }
}

建造者类(builder) :用于逐步构建产品对象,定义一步步设置对象属性的方法。
 

public class ComputerBuilder {
    // 必须的属性
    private String cpu;
    private String memory;
    private String disk;

    // 可选的属性
    private String graphicsCard;

    public ComputerBuilder setCpu(String cpu) {
        this.cpu = cpu;
        return this;
    }

    public ComputerBuilder setMemory(String memory) {
        this.memory = memory;
        return this;
    }

    public ComputerBuilder setDisk(String disk) {
        this.disk = disk;
        return this;
    }

    public ComputerBuilder setGraphicsCard(String graphicsCard) {
        this.graphicsCard = graphicsCard;
        return this;
    }

    // 创建 Computer 对象的方法
    public Computer build() {
        return new Computer(this);
    }
}

客户端使用代码(Product) :在实际需要创建对象的地方,通过建造者来构建对象。
 

public class BuilderClient {
    public static void main(String[] args) {
        // 使用建造者模式创建 Computer 对象
        Computer computer = new ComputerBuilder()
                .setCpu("Intel i7")
                .setMemory("16GB")
                .setDisk("512GB SSD")
                .setGraphicsCard("NVIDIA RTX 3060")
                .build();

        System.out.println(computer);
    }
}

建造者模式(Builder Pattern)是一种创建型设计模式,用于分步骤构造复杂对象。它允许你使用相同的构造过程创建不同的对象表示,尤其适用于对象包含多个组成部分且构造过程需要清晰分离的场景。

核心思想

将对象的构造过程表示分离:

  • 避免在对象类中使用多参数构造函数(避免"telescoping constructor"问题)

  • 提供清晰的步骤式构造接口

  • 支持构造不同表示的对象(如不同配置的产品)
     

  • 关注我 “codingba” ,了解更多,

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐