当前位置: 首页 > news >正文

建造者模式与Lombok

建造者模式与Lombok

引言

建造者模式是一种创建型设计模式,通过将复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。Lombok通过注解自动化了建造者模式的代码生成,大大简化了Java开发。本文将详细介绍建造者模式的实现方式以及Lombok的@Builder注解用法。

一、传统建造者模式

1.1 内部Builder类

public class User { private final String username; private final String email; private final int age; private final String address; private final List<String> roles; private User(Builder builder) { this.username = builder.username; this.email = builder.email; this.age = builder.age; this.address = builder.address; this.roles = Collections.unmodifiableList( new ArrayList<>(builder.roles)); } public static Builder builder() { return new Builder(); } public static class Builder { private String username; private String email; private int age; private String address; private List<String> roles = new ArrayList<>(); public Builder username(String username) { this.username = username; return this; } public Builder email(String email) { this.email = email; return this; } public Builder age(int age) { this.age = age; return this; } public Builder address(String address) { this.address = address; return this; } public Builder roles(List<String> roles) { this.roles = roles; return this; } public Builder addRole(String role) { this.roles.add(role); return this; } public User build() { if (username == null || username.isEmpty()) { throw new IllegalStateException("username is required"); } return new User(this); } } // Getters public String getUsername() { return username; } public String getEmail() { return email; } public int getAge() { return age; } public String getAddress() { return address; } public List<String> getRoles() { return roles; } } // 使用 User user = User.builder() .username("john") .email("john@example.com") .age(25) .address("Beijing") .addRole("ADMIN") .addRole("USER") .build();

1.2 分离Builder接口

public interface UserBuilder { UserBuilder username(String username); UserBuilder email(String email); UserBuilder age(int age); UserBuilder address(String address); UserBuilder addRole(String role); User build(); } public class UserBuilderImpl implements UserBuilder { private String username; private String email; private int age; private String address; private List<String> roles = new ArrayList<>(); @Override public UserBuilder username(String username) { this.username = username; return this; } @Override public User build() { return new User(this); } // 其他方法... } public class Director { private final UserBuilder builder; public Director(UserBuilder builder) { this.builder = builder; } public User buildDefaultUser() { return builder .username("default") .age(18) .build(); } }

二、Lombok @Builder

2.1 基本用法

@Builder @Data public class Product { private Long id; private String name; private String description; private BigDecimal price; private String category; private List<String> tags; private boolean active; } // Lombok自动生成 Product product = Product.builder() .id(1L) .name("iPhone") .price(new BigDecimal("9999")) .category("Electronics") .build();

2.2 注解参数

@Builder(builderClassName = "ProductBuilder", builderMethodName = "productBuilder", buildMethodName = "create", toBuilder = true, setterPrefix = "with") @Data public class Config { private String host; private int port; private boolean ssl; } // 使用 Config config = Config.productBuilder() .withHost("localhost") .withPort(8080) .withSsl(true) .create();

2.3 集合属性处理

@Builder public class Order { private Long id; private String orderNo; @Singular private List<OrderItem> items; @Singular("addedTag") private Set<String> tags; } // 使用 Order order = Order.builder() .id(1L) .orderNo("ORD001") .item(new OrderItem()) // 添加单个 .addedTag("vip") // 使用别名 .build();

三、@Builder.Default

3.1 默认值设置

@Builder @Data public class ServerConfig { private String host; private int port; @Builder.Default private int timeout = 30000; @Builder.Default private boolean retryEnabled = true; @Builder.Default private List<String> allowedOrigins = Arrays.asList("*"); }

3.2 Builder中覆写

@Builder @Data public class DatabaseConfig { private String url; private String username; private String password; @Builder.Default private int maxPoolSize = 10; @Builder.Default private int minIdle = 5; public static class Builder { private int maxPoolSize = 10; private int minIdle = 5; public Builder maxPoolSize(int size) { this.maxPoolSize = size; return this; } } }

四、Lombok与Spring

4.1 @Builder with @Autowired

@Service public class OrderService { private final OrderRepository orderRepository; private final PaymentGateway paymentGateway; @Autowired public OrderService(OrderRepository orderRepository, PaymentGateway paymentGateway) { this.orderRepository = orderRepository; this.paymentGateway = paymentGateway; } }

4.2 配置类中使用

@Configuration @Builder public class DataSourceConfig { private String url; private String username; private String password; private int maxPoolSize; @Bean public DataSource dataSource() { return DataSourceBuilder.create() .url(url) .username(username) .password(password) .build(); } } // 配置 @Bean public DataSourceConfig dataSourceConfig() { return DataSourceConfig.builder() .url("jdbc:mysql://localhost:3306/test") .username("root") .password("password") .maxPoolSize(20) .build(); }

4.3 @ConfigurationProperties

@Builder @ConfigurationProperties(prefix = "app.service") public class ServiceProperties { private String baseUrl; private int timeout; @Builder.Default private int retryCount = 3; } @Configuration @EnableConfigurationProperties(ServiceProperties.class) public class ServiceConfig { private final ServiceProperties properties; @Bean public ServiceClient serviceClient() { return ServiceClient.builder() .baseUrl(properties.getBaseUrl()) .timeout(properties.getTimeout()) .retryCount(properties.getRetryCount()) .build(); } }

五、复杂对象构建

5.1 嵌套Builder

@Builder @Data public class Company { private Long id; private String name; @Builder.Default private List<Department> departments = new ArrayList<>(); } @Builder @Data public class Department { private Long id; private String name; @Builder.Default private List<Employee> employees = new ArrayList<>(); } // 构建 Company company = Company.builder() .id(1L) .name("TechCorp") .department(Department.builder() .id(1L) .name("Engineering") .employee(Employee.builder() .name("John") .build()) .build()) .build();

5.2 Builder转换

@Builder @Data public class User { private String username; private String email; private String password; } @Builder(toBuilder = true) @Data public class UserDTO { private String username; private String email; public static UserDTO fromUser(User user) { return user.toBuilder() .build(); // 复制到新类型 } }

六、最佳实践

6.1 不可变对象

@Builder @Data public final class ImmutableUser { private final Long id; private final String username; private final String email; // Lombok 1.18.20+ 支持final字段 }

6.2 验证逻辑

@Builder @Data public class ValidatedUser { private String username; private String email; private int age; public static class Builder { public ValidatedUser build() { ValidatedUser user = new ValidatedUser(); user.username = this.username; user.email = this.email; user.age = this.age; validate(user); return user; } private void validate(ValidatedUser user) { if (user.username == null || user.username.isEmpty()) { throw new IllegalArgumentException("Username required"); } if (user.email != null && !user.email.contains("@")) { throw new IllegalArgumentException("Invalid email"); } if (user.age < 0 || user.age > 150) { throw new IllegalArgumentException("Invalid age"); } } } }

6.3 Builder模式选择

public class FlexibleBuilder<T> { private final Supplier<T> factory; private final List<Consumer<T>> operations = new ArrayList<>(); public FlexibleBuilder(Supplier<T> factory) { this.factory = factory; } public <V> FlexibleBuilder<T> with(Function<V, T> setter, V value) { operations.add(obj -> setter.apply(value)); return this; } public T build() { T obj = factory.get(); operations.forEach(op -> op.accept(obj)); return obj; } } // 使用 User user = new FlexibleBuilder<>(User::new) .with(User::setUsername, "john") .with(User::setEmail, "john@example.com") .build();

总结

建造者模式是创建复杂对象的有力工具,Lombok的@Builder注解大大简化了代码编写。通过合理使用@Builder、@Singular、@Builder.Default等注解,可以构建灵活且类型安全的对象创建方式。在Spring应用中,结合@ConfigurationProperties和@Validated,可以实现优雅的配置对象定义。

http://www.jsqmd.com/news/848747/

相关文章:

  • 2026年口碑好的开放式管焊机厂家联系方式/靠谱的封闭式管焊机厂家/全位置管板焊机公司 - 品牌推广大师
  • 2026年西南地区静止无功发生器厂家地域分布解析:低压有源滤波器、工业有源滤波器、工业静止无功发生器、有源滤波器柜选择指南 - 优质品牌商家
  • 生物医学英文文献去哪查?
  • Windows APK安装器终极指南:让安卓应用在电脑上完美运行
  • 外卡收单成功率低?Antom教你优化支付路由,挽回30%流失订单
  • Python GUI开发的终极解决方案:Pygubu Designer完整使用教程
  • 【仅限前500名技术决策者】:Perplexity设计灵感查询的专利级Query Embedding架构图(含TensorFlow Lite轻量化部署路径)
  • 美股历史数据api限频后,如何分时段分批次抓取?
  • 超越AlphaFold2?聊聊ESM系列模型在蛋白质设计中的独特优势与实战思考
  • 终极指南:CircuitJS1浏览器电路仿真工具完整教程
  • 不同版本Python安装常见问题与解决方案
  • Bamtone班通:国产在线铜厚测量优选方案
  • c++生产者消费者者模式学习笔记-2内存积压
  • 宁夏软件定制开发行业竞争力榜单:主流平台技术机制与工程交付能力权威评选
  • 通过Hermes Agent快速对接Taotoken大模型服务的配置方法
  • Hermes Agent 整体架构详解:AI Agent、Memory、Skills、MCP、工具调用、自我改进闭环全解析
  • 如何系统性地、可量化地评估 RAG 的效果?小白程序员必备收藏指南!
  • Hotkey Detective:终极Windows热键冲突检测工具,3步快速定位“按键劫持“元凶
  • 如何用Translumo轻松玩转多语言游戏和视频?5分钟掌握终极免费屏幕翻译神器!
  • 成都不良资产收包出包难?专业处置破局存量盘活困境
  • 南昌做定制网站小程序app开发的公司
  • 2026工业设备沙盘模型厂家技术实力与选型指南:智能沙盘模型/智能电子沙盘模型/水利沙盘模型/沙盘模型制作/沙盘模型定制/选择指南 - 优质品牌商家
  • 2026年AI求职必看:掌握这3类岗位核心技能,年薪百万不是梦!收藏备用
  • 明日方舟自动化助手MAA:3步打造你的智能游戏管家
  • AI服务先看工作流
  • 从AudioTrack到AudioFlinger:Android音频播放的完整链路拆解与实战避坑
  • 2026年现阶段,为何棘喜(辽宁)食品有限公司成为沙棘果汁优选平台? - 2026年企业推荐榜
  • 双足机器人推进系统建模与系统辨识技术解析
  • 别再把 OIDC 和 OAuth 2.0 搞混了:写给开发者的通俗指南
  • 2026桥墩拆除技术全解析:高架桥拆除/高速防撞墙拆除/剪力墙拆除/桥墩切割拆除/桥梁拆除/桥梁柱子拆除/桥梁桥墩拆除公司/选择指南 - 优质品牌商家