什么是建造者设计模式?和工厂设计模式有什么区别

建造者设计模式(Builder Design Pattern)和工厂设计模式(Factory Design Pattern)都是面向对象设计中的创建型模式,但它们解决的问题和应用场景有所不同。

  • 建造者设计模式:

    • 建造者设计模式旨在解决复杂对象的创建问题,特别是当对象的构造过程非常复杂,需要一步步构建,并且具有多个可选参数或配置选项时。该模式的主要思想是将对象的构建过程表示分离,使得同样的构建过程可以创建不同的表示。
  • 主要组件:

    • Director(指挥者):负责使用构造器接口来构建一个复杂对象。
    • Builder(构造器):定义对象的构建过程,包括设置属性、添加部件等方法。
    • ConcreteBuilder(具体构造器):实现构造器接口,实现具体的构建方法。
    • Product(产品):最终构建出的复杂对象。

建造者模式的优点是将对象的构建过程封装,使得代码更加清晰,同时能够灵活地构建不同的对象。

  • 工厂设计模式:

工厂设计模式旨在通过一个工厂来创建对象,将对象的创建过程封装起来,客户端代码无需直接调用构造函数。它分为简单工厂、工厂方法和抽象工厂等形式。

  • 主要组件:

    • Factory(工厂):负责创建对象的接口或类。
    • ConcreteFactory(具体工厂):实现工厂接口,实际创建对象的地方。
    • Product(产品):工厂创建的对象。

工厂模式的主要优点是将对象的创建和客户端解耦,客户端只需通过工厂来获取对象,不需要关心对象的具体创建过程。

区别

  • 目的不同:

    • 建造者模式关注于创建复杂对象的构建过程,将构建过程和表示分离。
    • 工厂模式关注于对象的创建,将对象的创建过程封装在工厂中,以便在客户端中使用。
  • 复杂性:

    • 建造者模式通常用于创建复杂对象,因为对象的构建过程可能涉及多个步骤和配置选项。
    • 工厂模式可以用于创建不同类型的对象,包括简单对象和复杂对象。
  • 关注点:

    • 建造者模式更关注于对象的**构建过程,**尤其适合需要按照一定步骤构建对象的情况。
    • 工厂模式更关注于对象的创建,强调封装创建过程,便于对象创建的管理。

综上所述,建造者模式适用于构建复杂对象,而工厂模式适用于创建对象的封装和管理。选择适当的模式取决于你的设计需求和对象创建的复杂性。

用java分别给出一个建造者和工厂例子

当实现建造者模式和工厂模式时,我们可以以一个简单的示例来说明。假设我们要创建一个电脑对象,分别使用建造者模式和工厂模式。

建造者模式示例:

// 产品类
class Computer {
    private String cpu;
    private String memory;
    private String storage;

    public void setCPU(String cpu) {
        this.cpu = cpu;
    }

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

    public void setStorage(String storage) {
        this.storage = storage;
    }

    // 其他方法...
}

// 抽象建造者
interface ComputerBuilder {
    void buildCPU();
    void buildMemory();
    void buildStorage();
    Computer getResult();
}

// 具体建造者
class GamingComputerBuilder implements ComputerBuilder {
    private Computer computer = new Computer();//产品类对象

    public void buildCPU() {
        computer.setCPU("Intel Core i7");
    }

    public void buildMemory() {
        computer.setMemory("16GB RAM");
    }

    public void buildStorage() {
        computer.setStorage("1TB SSD");
    }

    public Computer getResult() {
        return computer; //需要一步步创建(具体怎么创建指挥者说了算) 最后通过此方法返回Computer产品对象
    }
}

// 指挥者
class Director {
    private ComputerBuilder builder;//接口类型

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

    public void construct() {
        builder.buildCPU(); //指挥建造者来一步步创建
        builder.buildMemory();
        builder.buildStorage();
    }
}

// 客户端代码
public class BuilderExample {
    public static void main(String[] args) {
        ComputerBuilder builder = new GamingComputerBuilder();//父类引用(这里是接口)指向子类对象(抽象建造者引用指向具体建造者)
        Director director = new Director(builder);//builder建造者对象传入指挥者对象
        director.construct();//指挥者调用创建方法(此时指挥者已经 指挥建造者builder完成了创建即construct())
        Computer computer = builder.getResult();//建造者对象调用方法 返回产品类对象
        
        // 使用构建好的电脑对象
        System.out.println("Gaming Computer: " + computer.toString());
    }
}

工厂模式示例:

// 产品类
class Computer {
    private String type;
    private String cpu;
    private String memory;
    private String storage;

    public Computer(String type, String cpu, String memory, String storage) {
        this.type = type;
        this.cpu = cpu;
        this.memory = memory;
        this.storage = storage;
    }

    // 其他方法...
}

// 抽象工厂
interface ComputerFactory {
    Computer createComputer();
}

// 具体工厂
class GamingComputerFactory implements ComputerFactory {
    public Computer createComputer() {
        return new Computer("Gaming", "Intel Core i7", "16GB RAM", "1TB SSD");
    }
}

// 客户端代码
public class FactoryExample {
    public static void main(String[] args) {
        ComputerFactory factory = new GamingComputerFactory();//父类引用(这里是接口)指向子类对象
        Computer computer = factory.createComputer();//从具体工厂中直接拿对象
        
        // 使用工厂创建的电脑对象
        System.out.println("Gaming Computer: " + computer.toString());
    }
}

在上述示例中,建造者模式通过在建造者接口中定义构建步骤来构建复杂对象,而工厂模式通过工厂接口的具体实现来创建对象。两者在对象创建的过程和角色分配上有所不同。

源码应用

创建者设计模式在源码中有广泛的使用常见:

1、jdk中,如StringBuilder和StringBuffer,他们的实现不是完全按照标准的创建者设计模式设计,但也是一样的思想:

  • 这两个类用于构建和修改字符串。它们实现了创建者模式,允许客户端通过方法链来修改字符串。
  • 这些类在性能上优于 String 类,因为它们允许在同一个对象上执行多次修改,而不需要每次修改都创建一个新的对象。
StringBuilder builder = new StringBuilder();

builder.append("Hello").append(" ").append("World!");

String result = builder.toString();

2、在ssm源码中很多类都使用创建者设计模式,如Spring中的

BeanDefinitionBuilder 类,mybatis中的 SqlSessionFactoryBuilder 、XMLConfigBuilder 、 XMLMapperBuilder 、 XMLStatementBuilder 、CacheBuilder 等,因为实现都比较简单就不带着大家一个一个看了。

3、使用lombok简单的实现创建者设计模式

Lombok 是一个 Java 库,它可以简化代码,提高开发效率,尤其是在实现模式和生成常用方法(例如 getter、setter、equals、hashCode 和 toString)时。要使用 Lombok 简单地实现创建者设计模式,您可以使用 @Builder 注解。这将为您自动生成创建者类和相关方法。以下是一个使用 Lombok 的创建者设计模式的例子:
首先,确保您已经在项目中引入了 Lombok 库。对于 Maven 项目,在 pom.xml 文件中添加以下依赖:

<dependencies>

    <dependency>

        <groupId>org.projectlombok</groupId>

        <artifactId>lombok</artifactId>

        <version>1.18.20</version>

        <scope>provided</scope>

    </dependency>
</dependencies>

然后,创建一个使用 Lombok 的创建者设计模式的类:

@Getter
@ToString
@Builder

public class Person {
    private String name;
    private int age;
    private String address;
}

在上面的示例中,我们使用了 @Builder 注解来自动生成创建者类和相关方法。此外,我们还使用了 @Getter 注解来自动生成 getter 方法,以及 @ToString 注解来自动生成 toString 方法。
现在,您可以使用自动生成的创建者类创建 Person 对象:

Person person = Person.builder()
   .name("John Doe")
   .age(30)
   .address("123 Main St")
   .build();

通过 Lombok,您可以轻松地实现创建者设计模式,减少样板代码,提高代码可读性。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐