【设计模式】builder 创建者设计模式详解(包含电商应用场景及代码示例)

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。【设计模式】builder 创建者设计模式详解(包含电商应用场景及代码示例),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、builder 简介

在常见的设计模式中,“Builder” 通常是指一种设计模式,而不是具体的类或方法。Builder 模式是一种创建型设计模式,其目的是通过提供一个独立的构建器类来构建一个复杂对象。

建造者模式(Builder Pattern) 是一种创建型设计模式,它的主要目标是为了将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

1、主要角色

  • 产品(Product):表示被构建的复杂对象。在建造过程完成后,该对象通常包含多个部件。
  • 抽象建造者(Builder):声明了创建产品各个部件的抽象接口。通常包含创建和返回产品的方法。
  • 具体建造者(Concrete Builder):实现了抽象建造者接口,负责实际构建产品的各个部件。具体建造者通常会有一个与产品相关的成员变量,用于保存当前产品的状态。
  • 指导者(Director):负责使用建造者对象构建产品。指导者通常不知道具体产品的类型和内部结构,仅仅负责按照一定的构建步骤调用建造者的方法。

在 Java 中,Builder 模式通常由一个包含所有构建步骤的内部静态类(称为 Builder 类)来实现。这个 Builder 类负责设置对象的各个属性,最后通过一个 build() 方法来构建目标对象。

总体而言,Builder 模式是通过一个独立的构建器类来创建对象,使得对象的构建过程更加灵活和清晰。

二、builder 用法及实现

1、手写builder类

一般来说,builder 的用法如下:

  • 创建一个静态内部类作为建造者(Builder):

        private String property1;
        private int property2;
    
        // 私有构造函数,限制直接实例化
        private MyClass() {
        }
    
        // Getter 方法省略...
    
        // 静态内部类作为建造者
        public static class Builder {
            private MyClass instance = new MyClass();
    
            public Builder withProperty1(String value) {
                instance.property1 = value;
                return this;
            }
    
            public Builder withProperty2(int value) {
                instance.property2 = value;
                return this;
            }
    
            public MyClass build() {
                return instance;
            }
        }
    
        // 其他静态工厂方法或实例方法...
    
        // 示例:使用 builder() 创建对象
        public static Builder builder() {
            return new Builder();
        }
     } 
    
  • 使用建造者设置属性:

    MyClass myObject = MyClass.builder()
        .withProperty1("value1")
        .withProperty2(42)
        .build(); 
    

通过这种方式,你可以在创建对象的时候逐步设置属性,而不是通过构造函数传递参数。这样的设计使得代码更加清晰,易于维护,尤其当有多个可选属性时,建造者模式可以提供更好的灵活性。

2、Lombok实现

使用 Lombok 这样的工具,它提供了 @Builder 注解,该注解可以用于生成 Builder 模式相关的代码。下面是一个使用 Lombok 的 @Builder 注解的简单示例:详情参考【注解】@Builder、@SuperBuilder Lombok 中的建设者

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class Example {
    private final String name;
    private final int age;
}
// 在其他类中使用
Example example = Example.builder()
        .name("John")
        .age(25)
        .build();

在这个示例中,Builder 注解帮助生成了一个名为 builder 的静态内部类,该类用于创建 Example 对象的实例。这种方式使得对象的创建更加清晰和方便。

请注意,@Builder 是 Lombok 提供的功能,如果你没有使用 Lombok,你需要手动编写 Builder 模式的代码。

三、作用和优势

1、工作流程

  • 客户端(Client):创建指导者对象,并指定一个具体的建造者对象。
  • 指导者(Director):调用具体建造者的一系列方法,按照一定的步骤来构建产品。
  • 具体建造者(Concrete Builder):实现了具体的构建步骤,负责构建产品的各个部件。
  • 产品(Product):表示最终构建成功的对象。

2、优点

  • 分离构建和表示:建造者模式将对象的构建和最终表示分离,使得相同的构建过程可以创建不同的表示。
  • 更好的控制构建过程:通过指导者来控制构建过程,可以灵活地配置和改变产品的构建流程。
  • 更好的复用性:可以通过不同的具体建造者来创建不同类型的产品,提高了代码的复用性。
  • 更好的扩展性:增加新的具体建造者无需修改指导者的代码,符合开闭原则。

四、应用场景

  • 需要创建复杂对象:当对象的构建过程较为复杂,涉及多个部件组合,且这些部件可能存在多种组合方式时,可以考虑使用建造者模式。
  • 对象的构建步骤顺序不固定:如果对象的构建步骤的顺序不固定,或者某些步骤可以省略,可以通过建造者模式更灵活地构建对象。
  • 想要避免使用过多的构造方法:在类的构造方法中,参数的组合可能有多种情况,如果为每一种情况都提供一个构造方法,会导致构造方法的数量急剧增加。建造者模式可以通过一系列的方法来设置对象的不同部分,避免构造方法的爆炸性增长。
  • 希望在创建对象时能够更好地控制对象的构建过程:通过使用指导者(Director)来封装对象的构建过程,客户端只需要指定具体的建造者和调用指导者的构建方法,而无需关心对象的具体构建过程。
  • 想要避免在客户端暴露产品的内部表示:建造者模式将产品的构建和最终表示分离,客户端只需要关心产品的最终状态而不需要知道具体的构建细节,从而降低了客户端与产品的耦合度。

总的来说,建造者模式适用于需要创建复杂对象,且构建过程灵活多变的场景。在这种模式下,将对象的构建过程封装在具体建造者中,通过指导者来统一调度,使得客户端可以更方便地构建出所需的对象。

五、应用实例(电商)

在电商项目中,一个典型的场景是创建订单(Order)。订单通常包含多个部分,例如订单项、收货地址、支付信息等,而每个部分的构建可能涉及到多个步骤和参数。建造者模式在这种情况下可以很好地应用。

让我们考虑一个简化的订单创建过程,使用建造者模式来构建订单对象。假设订单包括订单号、订单项列表、收货地址、支付信息等。

1、首先,定义订单对象:

// 订单对象
public class Order {
    private String orderNumber;
    private List<OrderItem> orderItems;
    private String shippingAddress;
    private String paymentInfo;

    // 构造方法私有化,通过建造者来构建对象
    private Order() {
    }

    // 提供获取订单信息的方法
    // ...
}

2、然后,定义订单项对象:

// 订单项对象
public class OrderItem {
    private String productCode;
    private int quantity;

    // 构造方法
    public OrderItem(String productCode, int quantity) {
        this.productCode = productCode;
        this.quantity = quantity;
    }

    // 提供获取订单项信息的方法
    // ...
}

3、接下来,定义订单的建造者(OrderBuilder):

// 订单建造者
public class OrderBuilder {
    private Order order;

    public OrderBuilder() {
        this.order = new Order();
    }

    public OrderBuilder setOrderNumber(String orderNumber) {
        order.orderNumber = orderNumber;
        return this;
    }

    public OrderBuilder addOrderItem(String productCode, int quantity) {
        if (order.orderItems == null) {
            order.orderItems = new ArrayList<>();
        }
        order.orderItems.add(new OrderItem(productCode, quantity));
        return this;
    }

    public OrderBuilder setShippingAddress(String shippingAddress) {
        order.shippingAddress = shippingAddress;
        return this;
    }

    public OrderBuilder setPaymentInfo(String paymentInfo) {
        order.paymentInfo = paymentInfo;
        return this;
    }

    public Order build() {
        return order;
    }
}

4、最后,在客户端中使用建造者模式来构建订单:

public class Main {
    public static void main(String[] args) {
        // 使用建造者构建订单
        Order order = new OrderBuilder()
                .setOrderNumber("123456")
                .addOrderItem("P001", 2)
                .addOrderItem("P002", 1)
                .setShippingAddress("123 Main St, City")
                .setPaymentInfo("Credit Card")
                .build();

        // 打印订单信息
        System.out.println("Order Number: " + order.getOrderNumber());
        System.out.println("Shipping Address: " + order.getShippingAddress());
        System.out.println("Payment Info: " + order.getPaymentInfo());
        System.out.println("Order Items: " + order.getOrderItems());
    }
}

在这个例子中,通过使用建造者模式,客户端可以按照自己的需求逐步设置订单的各个部分,最后调用 build() 方法生成订单对象。这种方式既灵活又可读性好,而且使得订单对象的创建过程与客户端解耦。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/199190.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!