news 2026/5/20 2:38:04

建造者模式与Lombok

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
建造者模式与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,可以实现优雅的配置对象定义。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 2:36:43

美股历史数据api限频后,如何分时段分批次抓取?

最近在做美股历史数据抓取的时候&#xff0c;我才真切感受到限频的尴尬。数据源再丰富&#xff0c;如果一味往接口上狂拉&#xff0c;限频规则就会立刻给你“降速”。我手上有几个项目&#xff0c;都涉及美股分时行情和历史交易数据&#xff0c;尤其是在回测策略和研究行情的时…

作者头像 李华
网站建设 2026/5/20 2:35:26

3步掌握MAA明日方舟助手:如何实现游戏日常全自动化

3步掌握MAA明日方舟助手&#xff1a;如何实现游戏日常全自动化 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手&#xff0c;全日常一键长草&#xff01;| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: https://gitcod…

作者头像 李华
网站建设 2026/5/20 2:34:31

NCMconverter终极指南:3步解锁加密音乐,实现跨平台播放自由

NCMconverter终极指南&#xff1a;3步解锁加密音乐&#xff0c;实现跨平台播放自由 【免费下载链接】NCMconverter NCMconverter将ncm文件转换为mp3或者flac文件 项目地址: https://gitcode.com/gh_mirrors/nc/NCMconverter 还在为下载的音乐只能在特定软件播放而烦恼吗…

作者头像 李华
网站建设 2026/5/20 2:34:22

3步掌握LilToon:Unity卡通渲染着色器的终极解决方案

3步掌握LilToon&#xff1a;Unity卡通渲染着色器的终极解决方案 【免费下载链接】lilToon Feature-rich shaders for avatars 项目地址: https://gitcode.com/gh_mirrors/li/lilToon LilToon是一个功能丰富的Unity卡通渲染着色器集合&#xff0c;专为虚拟角色和卡通风格…

作者头像 李华