说说建造者模式

B站影视 日本电影 2025-09-26 04:28 1

摘要:建造者模式是一种创建型设计模式,旨在提供一种灵活的解决方案,用于创建复杂的对象,什么是复杂对象呢?简单来说,复杂对象是指那些包含多个成员属性的对象,这些成员属性也称为部件或零件。它通过将对象的构建过程和表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式是一种创建型设计模式,旨在提供一种灵活的解决方案,用于创建复杂的对象,什么是复杂对象呢?简单来说,复杂对象是指那些包含多个成员属性的对象,这些成员属性也称为部件或零件。它通过将对象的构建过程和表示分离,使得同样的构建过程可以创建不同的表示。

构造方法参数过多,示例代码如下:Order order = new Order("202509250001", 9527, "2025-09-25 00:00:00", 100.00, "待支付", "微信支付");

大家可以看到,这个构造方法的参数太多了,写着写着可能你都分不清哪个参数对应哪个属性。可能你将"微信支付"赋值给了支付状态属性,将" #技术分享待支付"赋值给了支付方式属性都没发现有问题,因为这两个字段都是字符串类型,编译器并不会报错。只要参数超过5个,调用者都会陷入参数地狱。

建造者模式的四个角色:

Product :产品类,最终要构建的复杂对象。Builder :抽象建造者,定义构建步骤的接口。ConcreteBuilder :具体建造者,实现抽象建造者的接口,实现构建步骤并返回产品。Direct :指挥者(可选),控制构建过程。

很多系统中都会有下订单这个操作,这个订单表里面是包含了很多字段的,比如订单号、用户 id、下单时间、订单总金额、订单状态、支付方式等多个可选部件,建造者模式可以灵活地进行组装,下面直接上代码。

1.产品类

public class Order { private String orderNum; private int userId; private Date orderTime; private BigDecimal totalPrice; private String status; private String paymentMethod;public String getOrderNum { return orderNum; }public void setOrderNum(String orderNum) { this.orderNum = orderNum; }public int getUserId { return userId; }public void setUserId(int userId) { this.userId = userId; }public LocalDateTime getOrderTime { return orderTime; }public void setOrderTime(Date orderTime) { this.orderTime = orderTime; }public BigDecimal getTotalPrice { return totalPrice; }public void setTotalPrice(BigDecimal totalPrice) { this.totalPrice = totalPrice; }public String getStatus { return status; }public void setStatus(String status) { this.status = status; }public String getPaymentMethod { return paymentMethod; }public void setPaymentMethod(String paymentMethod) { this.paymentMethod = paymentMethod; }@Override public String toString { return "Order{" + "orderNum='" + orderNum + '\'' + ", userId=" + userId + ", orderTime=" + orderTime + ", totalPrice=" + totalPrice + ", status='" + status + '\'' + ", paymentMethod='" + paymentMethod + '\'' + '}'; } }

2.抽象建造者

public interface OrderBuilder { void buildOrderNum(String orderNum); void buildUserId(int userId); void buildOrderTime(Date orderTime); void buildTotalPrice(BigDecimal totalPrice); void buildStatus(String status); void buildPaymentMethod(String paymentMethod);Order build; }

抽象建造者中还声明了一个得到产品建造后结果的方法 build。

3.具体建造者

public class ConcreteOrderBuilder implements OrderBuilder{private Order order = new Order; @Override public void buildOrderNum(String orderNum) { order.setOrderNum(orderNum); } @Override public void buildUserId(int userId) { order.setUserId(userId); } @Override public void buildOrderTime(Date orderTime) { order.setOrderTime(orderTime); } @Override public void buildTotalPrice(BigDecimal totalPrice) { order.setTotalPrice(totalPrice); } @Override public void buildStatus(String status) { order.setStatus(status); } @Override public void buildPaymentMethod(String paymentMethod) { order.setPaymentMethod(paymentMethod); }public Order build { return order; } }

4.指挥者

public class Director { private OrderBuilder orderBuilder; public Director(OrderBuilder orderBuilder) { this.orderBuilder = orderBuilder; }public Order construct(String orderNum, int userId, Date orderTime, BigDecimal totalPrice, String status, String paymentMethod) { orderBuilder.buildOrderNum(orderNum); orderBuilder.buildUserId(userId); orderBuilder.buildOrderTime(orderTime); orderBuilder.buildTotalPrice(totalPrice); orderBuilder.buildStatus(status); orderBuilder.buildPaymentMethod(paymentMethod); return orderBuilder.build; } }

5.客户端

public class Client { public static void main(String args) { OrderBuilder builder = new ConcreteOrderBuilder; Director director = new Director(builder); Order order = director.construct("202509250001", 9527,new Date, new BigDecimal(100), "待支付", "微信支付");OrderBuilder builder1 = new ConcreteOrderBuilder; builder1.buildOrderNum("202509250001"); builder1.buildUserId(9527); builder1.buildOrderTime(new Date); builder1.buildTotalPrice(new BigDecimal(100)); builder1.buildStatus("待支付"); builder1.buildPaymentMethod("微信支付"); Order order1 = builder1.build; } }public class Order { private String orderNum; private int userId; private Date orderTime; private BigDecimal totalPrice; private String status; private String paymentMethod;private Order(String orderNum, int userId, Date orderTime, BigDecimal totalPrice, String status, String paymentMethod) { this.orderNum = orderNum; this.userId = userId; this.orderTime = orderTime; this.totalPrice = totalPrice; this.status = status; this.paymentMethod = paymentMethod; }@Override public String toString { return "Order{" + "orderNum='" + orderNum + '\'' + ", userId=" + userId + ", orderTime=" + orderTime + ", totalPrice=" + totalPrice + ", status='" + status + '\'' + ", paymentMethod='" + paymentMethod + '\'' + '}'; }public static class Builder { private String orderNum; private int userId; private Date orderTime; private BigDecimal totalPrice; private String status; private String paymentMethod; public Builder buildOrderNum(String orderNum) { this.orderNum = orderNum; return this; }public Builder buildUserId(int userId) { this.userId = userId; return this; } public Builder buildOrderTime(Date orderTime) { this.orderTime = orderTime; return this; } public Builder buildTotalPrice(BigDecimal totalPrice) { this.totalPrice = totalPrice; return this; } public Builder buildStatus(String status) { this.status = status; return this; } public Builder buildPaymentMethod(String paymentMethod) { this.paymentMethod = paymentMethod; return this; } public Order build { if(status == null){ throw new IllegalStateException("订单状态不能为空"); } return new Order(orderNum, userId, orderTime, totalPrice, status, paymentMethod); } } }

建造者类

public class ConcreteOrderBuilder {private Order order = new Order;public ConcreteOrderBuilder buildOrderNum { order.setOrderNum("202509250001"); return this; }public ConcreteOrderBuilder buildUserId { order.setUserId(9527); return this; }public ConcreteOrderBuilder buildOrderTime { order.setOrderTime(LocalDateTime.now); return this; }public ConcreteOrderBuilder buildTotalPrice { order.setTotalPrice(new BigDecimal(100)); return this; }public ConcreteOrderBuilder buildStatus { order.setStatus("待支付"); return this; }public ConcreteOrderBuilder buildPaymentMethod { order.setPaymentMethod("微信支付"); return this; }public Order getResult { return order; } }public class Client { public static void main(String args) { Order order = new Order.Builder .buildOrderNum("202509250001") .buildOrderTime(new Date) .buildPaymentMethod("微信支付") .buildStatus("1") .buildTotalPrice(BigDecimal.valueOf(100.00)) .buildUserId(9527) .build; System.out.println(order); }}

通过传统版本中,Director 指挥者类中的 construct 方法可以看到,这种方式比较适合构建过程固定的场景。而链式调用版本,通过返回 this 实现链式调用,适合构建过程灵活、需要动态配置的场景。

如果你的项目中有使用到 Lombok,那么你应该知道它提供了一个@Builder 注解,Lombok 的@Builder 注解通过自动生成构建者模式代码实现链式调用,其核心机制是为目标类创建内部静态 Builder 类,每个属性对应生成同名链式方法(返回 Builder 实例),最终通过 build方法完成对象构建。(Lombok 在编译期修改 AST,生成包含完整链式方法的静态内部类。)

实体类中字段太多,比如超过5个。存在参数校验逻辑,比如上述例子中的userId字段要求必填,可以在build方法中加入校验逻辑。

来源:墨码行者

相关推荐