建造者模式详解
目录
建造者模式简介
定义
建造者模式(Builder Pattern)是一种创建型设计模式,它将复杂对象的构建过程分离出来,使得同样的构建过程可以创建不同的表示。建造者模式允许用户通过指定复杂对象的类型和内容来构建它们,而不需要知道内部的具体构建细节。
核心思想
- 分离构建过程:将复杂对象的构建过程与表示分离
- 分步构建:通过一步步的构建过程创建复杂对象
- 灵活配置:可以灵活配置对象的各个部分
- 封装构建逻辑:将构建逻辑封装在建造者中
模式结构
- Product(产品类):要构建的复杂对象
- Builder(抽象建造者):定义构建产品各个部分的抽象接口
- ConcreteBuilder(具体建造者):实现抽象建造者接口,构建和装配产品的各个部分
- Director(指挥者):调用建造者对象创建产品实例
- Client(客户端):使用指挥者创建产品
核心流程
建造者模式流程图
基本实现流程
1. 定义产品类
// 产品类
public class Computer {
private String cpu;
private String memory;
private String hardDisk;
private String graphicsCard;
private String monitor;
public Computer() {}
// getter和setter方法
public String getCpu() { return cpu; }
public void setCpu(String cpu) { this.cpu = cpu; }
public String getMemory() { return memory; }
public void setMemory(String memory) { this.memory = memory; }
public String getHardDisk() { return hardDisk; }
public void setHardDisk(String hardDisk) { this.hardDisk = hardDisk; }
public String getGraphicsCard() { return graphicsCard; }
public void setGraphicsCard(String graphicsCard) { this.graphicsCard = graphicsCard; }
public String getMonitor() { return monitor; }
public void setMonitor(String monitor) { this.monitor = monitor; }
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", memory='" + memory + '\'' +
", hardDisk='" + hardDisk + '\'' +
", graphicsCard='" + graphicsCard + '\'' +
", monitor='" + monitor + '\'' +
'}';
}
}
2. 定义抽象建造者
// 抽象建造者
public abstract class ComputerBuilder {
protected Computer computer = new Computer();
public abstract void buildCpu();
public abstract void buildMemory();
public abstract void buildHardDisk();
public abstract void buildGraphicsCard();
public abstract void buildMonitor();
public Computer getComputer() {
return computer;
}
}
3. 实现具体建造者
// 具体建造者 - 游戏电脑
public class GamingComputerBuilder extends ComputerBuilder {
@Override
public void buildCpu() {
computer.setCpu("Intel i7-12700K");
}
@Override
public void buildMemory() {
computer.setMemory("32GB DDR4");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("1TB NVMe SSD");
}
@Override
public void buildGraphicsCard() {
computer.setGraphicsCard("RTX 4080");
}
@Override
public void buildMonitor() {
computer.setMonitor("27寸 4K 144Hz");
}
}
// 具体建造者 - 办公电脑
public class OfficeComputerBuilder extends ComputerBuilder {
@Override
public void buildCpu() {
computer.setCpu("Intel i5-12400");
}
@Override
public void buildMemory() {
computer.setMemory("16GB DDR4");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("512GB SSD");
}
@Override
public void buildGraphicsCard() {
computer.setGraphicsCard("集成显卡");
}
@Override
public void buildMonitor() {
computer.setMonitor("24寸 1080p");
}
}
4. 定义指挥者
// 指挥者
public class ComputerDirector {
private ComputerBuilder builder;
public ComputerDirector(ComputerBuilder builder) {
this.builder = builder;
}
public void setBuilder(ComputerBuilder builder) {
this.builder = builder;
}
public Computer construct() {
builder.buildCpu();
builder.buildMemory();
builder.buildHardDisk();
builder.buildGraphicsCard();
builder.buildMonitor();
return builder.getComputer();
}
}
5. 客户端使用
public class Client {
public static void main(String[] args) {
// 创建游戏电脑
ComputerBuilder gamingBuilder = new GamingComputerBuilder();
ComputerDirector director = new ComputerDirector(gamingBuilder);
Computer gamingComputer = director.construct();
System.out.println("游戏电脑: " + gamingComputer);
// 创建办公电脑
ComputerBuilder officeBuilder = new OfficeComputerBuilder();
director.setBuilder(officeBuilder);
Computer officeComputer = director.construct();
System.out.println("办公电脑: " + officeComputer);
}
}
重难点分析
重难点1:链式调用建造者模式
问题描述
如何实现链式调用的建造者模式,提高代码的可读性和易用性。
解决方案
// 链式调用建造者模式
public class Computer {
private String cpu;
private String memory;
private String hardDisk;
private String graphicsCard;
private String monitor;
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.memory = builder.memory;
this.hardDisk = builder.hardDisk;
this.graphicsCard = builder.graphicsCard;
this.monitor = builder.monitor;
}
public static class Builder {
private String cpu;
private String memory;
private String hardDisk;
private String graphicsCard;
private String monitor;
public Builder setCpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder setMemory(String memory) {
this.memory = memory;
return this;
}
public Builder setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
return this;
}
public Builder setGraphicsCard(String graphicsCard) {
this.graphicsCard = graphicsCard;
return this;
}
public Builder setMonitor(String monitor) {
this.monitor = monitor;
return this;
}
public Computer build() {
return new Computer(this);
}
}
// getter方法
public String getCpu() { return cpu; }
public String getMemory() { return memory; }
public String getHardDisk() { return hardDisk; }
public String getGraphicsCard() { return graphicsCard; }
public String getMonitor() { return monitor; }
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", memory='" + memory + '\'' +
", hardDisk='" + hardDisk + '\'' +
", graphicsCard='" + graphicsCard + '\'' +
", monitor='" + monitor + '\'' +
'}';
}
}
// 使用示例
public class Client {
public static void main(String[] args) {
Computer computer = new Computer.Builder()
.setCpu("Intel i7-12700K")
.setMemory("32GB DDR4")
.setHardDisk("1TB NVMe SSD")
.setGraphicsCard("RTX 4080")
.setMonitor("27寸 4K 144Hz")
.build();
System.out.println(computer);
}
}
重难点2:建造者模式的验证和约束
问题描述
如何在建造过程中添加验证和约束,确保构建的对象是有效的。
解决方案
// 带验证的建造者模式
public class User {
private final String username;
private final String email;
private final int age;
private final String phone;
private User(Builder builder) {
this.username = builder.username;
this.email = builder.email;
this.age = builder.age;
this.phone = builder.phone;
}
public static class Builder {
private String username;
private String email;
private int age;
private String phone;
public Builder setUsername(String username) {
if (username == null || username.trim().isEmpty()) {
throw new IllegalArgumentException("用户名不能为空");
}
this.username = username;
return this;
}
public Builder setEmail(String email) {
if (email == null || !email.contains("@")) {
throw new IllegalArgumentException("邮箱格式不正确");
}
this.email = email;
return this;
}
public Builder setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄必须在0-150之间");
}
this.age = age;
return this;
}
public Builder setPhone(String phone) {
if (phone != null && !phone.matches("\\d{11}")) {
throw new IllegalArgumentException("手机号格式不正确");
}
this.phone = phone;
return this;
}
public User build() {
// 构建时验证
if (username == null) {
throw new IllegalStateException("用户名不能为空");
}
if (email == null) {
throw new IllegalStateException("邮箱不能为空");
}
if (age <= 0) {
throw new IllegalStateException("年龄必须大于0");
}
return new User(this);
}
}
// getter方法
public String getUsername() { return username; }
public String getEmail() { return email; }
public int getAge() { return age; }
public String getPhone() { return phone; }
}
重难点3:建造者模式的线程安全
问题描述
在多线程环境下,如何确保建造者模式的线程安全。
解决方案
// 线程安全的建造者模式
public class ThreadSafeBuilder {
private final Object lock = new Object();
private volatile String field1;
private volatile String field2;
private volatile int field3;
public ThreadSafeBuilder setField1(String field1) {
synchronized (lock) {
this.field1 = field1;
return this;
}
}
public ThreadSafeBuilder setField2(String field2) {
synchronized (lock) {
this.field2 = field2;
return this;
}
}
public ThreadSafeBuilder setField3(int field3) {
synchronized (lock) {
this.field3 = field3;
return this;
}
}
public Product build() {
synchronized (lock) {
return new Product(field1, field2, field3);
}
}
}
// 使用不可变对象的建造者模式
public class ImmutableProduct {
private final String field1;
private final String field2;
private final int field3;
private ImmutableProduct(Builder builder) {
this.field1 = builder.field1;
this.field2 = builder.field2;
this.field3 = builder.field3;
}
public static class Builder {
private String field1;
private String field2;
private int field3;
public Builder setField1(String field1) {
this.field1 = field1;
return this;
}
public Builder setField2(String field2) {
this.field2 = field2;
return this;
}
public Builder setField3(int field3) {
this.field3 = field3;
return this;
}
public ImmutableProduct build() {
return new ImmutableProduct(this);
}
}
}
重难点4:建造者模式与工厂模式的区别
问题描述
建造者模式与工厂模式在结构和用途上的区别。
解决方案
// 工厂模式:关注对象创建
public class ComputerFactory {
public static Computer createGamingComputer() {
Computer computer = new Computer();
computer.setCpu("Intel i7-12700K");
computer.setMemory("32GB DDR4");
computer.setHardDisk("1TB NVMe SSD");
computer.setGraphicsCard("RTX 4080");
computer.setMonitor("27寸 4K 144Hz");
return computer;
}
public static Computer createOfficeComputer() {
Computer computer = new Computer();
computer.setCpu("Intel i5-12400");
computer.setMemory("16GB DDR4");
computer.setHardDisk("512GB SSD");
computer.setGraphicsCard("集成显卡");
computer.setMonitor("24寸 1080p");
return computer;
}
}
// 建造者模式:关注构建过程
public class ComputerBuilder {
private Computer computer = new Computer();
public ComputerBuilder setCpu(String cpu) {
computer.setCpu(cpu);
return this;
}
public ComputerBuilder setMemory(String memory) {
computer.setMemory(memory);
return this;
}
public ComputerBuilder setHardDisk(String hardDisk) {
computer.setHardDisk(hardDisk);
return this;
}
public ComputerBuilder setGraphicsCard(String graphicsCard) {
computer.setGraphicsCard(graphicsCard);
return this;
}
public ComputerBuilder setMonitor(String monitor) {
computer.setMonitor(monitor);
return this;
}
public Computer build() {
return computer;
}
}
// 关键区别:
// 1. 工厂模式:创建预定义的对象
// 2. 建造者模式:构建自定义的对象
// 3. 工厂模式:关注对象类型
// 4. 建造者模式:关注构建过程
Spring中的源码分析
Spring Boot的建造者模式应用
// SpringApplicationBuilder
public class SpringApplicationBuilder {
private SpringApplication application;
private ConfigurableEnvironment environment;
private boolean webEnvironment;
private boolean headless = true;
private boolean registerShutdownHook = true;
private Set<String> additionalProfiles = new HashSet<>();
private String[] args;
public SpringApplicationBuilder(Class<?>... sources) {
this.application = new SpringApplication(sources);
}
public SpringApplicationBuilder sources(Class<?>... sources) {
this.application.getSources().addAll(Arrays.asList(sources));
return this;
}
public SpringApplicationBuilder profiles(String... profiles) {
this.application.setAdditionalProfiles(profiles);
return this;
}
public SpringApplicationBuilder environment(ConfigurableEnvironment environment) {
this.environment = environment;
return this;
}
public SpringApplicationBuilder web(boolean webEnvironment) {
this.webEnvironment = webEnvironment;
return this;
}
public SpringApplicationBuilder headless(boolean headless) {
this.headless = headless;
return this;
}
public SpringApplicationBuilder registerShutdownHook(boolean registerShutdownHook) {
this.registerShutdownHook = registerShutdownHook;
return this;
}
public SpringApplicationBuilder run(String... args) {
this.args = args;
return this;
}
public ConfigurableApplicationContext build() {
if (this.application == null) {
throw new IllegalStateException("No sources configured");
}
if (this.environment != null) {
this.application.setEnvironment(this.environment);
}
if (this.webEnvironment) {
this.application.setWebApplicationType(WebApplicationType.SERVLET);
}
if (this.headless) {
System.setProperty("java.awt.headless", "true");
}
if (this.registerShutdownHook) {
this.application.setRegisterShutdownHook(true);
}
if (this.args != null) {
this.application.setMainArguments(this.args);
}
return this.application.run(this.args);
}
}
Spring Security的建造者模式
// HttpSecurity
public class HttpSecurity extends AbstractHttpConfigurer<HttpSecurity, HttpSecurity> {
private final RequestMatcherConfigurer requestMatcherConfigurer;
private final List<Filter> filters = new ArrayList<>();
private final Map<Class<? extends Filter>, Filter> filterToFilter = new HashMap<>();
public HttpSecurity requestMatchers(RequestMatcher... requestMatchers) {
this.requestMatcherConfigurer.requestMatchers(requestMatchers);
return this;
}
public HttpSecurity authorizeRequests() {
return authorizeRequests(AuthorizationManagerRequestMatcherRegistry::new);
}
public HttpSecurity authorizeHttpRequests(AuthorizationManagerRequestMatcherRegistry.Customizer customizer) {
AuthorizationManagerRequestMatcherRegistry registry = new AuthorizationManagerRequestMatcherRegistry(this);
customizer.customize(registry);
return this;
}
public HttpSecurity formLogin() {
return formLogin(Customizer.withDefaults());
}
public HttpSecurity formLogin(Customizer<FormLoginConfigurer<HttpSecurity>> formLoginCustomizer) {
formLoginCustomizer.customize(getOrApply(new FormLoginConfigurer<>()));
return this;
}
public HttpSecurity httpBasic() {
return httpBasic(Customizer.withDefaults());
}
public HttpSecurity httpBasic(Customizer<HttpBasicConfigurer<HttpSecurity>> httpBasicCustomizer) {
httpBasicCustomizer.customize(getOrApply(new HttpBasicConfigurer<>()));
return this;
}
public HttpSecurity csrf() {
return csrf(Customizer.withDefaults());
}
public HttpSecurity csrf(Customizer<CsrfConfigurer<HttpSecurity>> csrfCustomizer) {
csrfCustomizer.customize(getOrApply(new CsrfConfigurer<>()));
return this;
}
public HttpSecurity sessionManagement() {
return sessionManagement(Customizer.withDefaults());
}
public HttpSecurity sessionManagement(Customizer<SessionManagementConfigurer<HttpSecurity>> sessionManagementCustomizer) {
sessionManagementCustomizer.customize(getOrApply(new SessionManagementConfigurer<>()));
return this;
}
}
Spring Data的建造者模式
// JpaProperties
@ConfigurationProperties(prefix = "spring.jpa")
public class JpaProperties {
private Map<String, String> properties = new HashMap<>();
private Hibernate hibernate = new Hibernate();
private boolean openInView = true;
private boolean showSql = false;
private Database database;
private DatabasePlatform databasePlatform;
private String databaseAction;
private boolean generateDdl = false;
public static class Hibernate {
private String ddlAuto;
private String namingPhysicalStrategy;
private String namingImplicitStrategy;
private String namingStrategy;
private String useSqlComments;
private String formatSql;
private String jdbcTimeZone;
private String orderInserts;
private String orderUpdates;
private String batchSize;
private String batchVersionedData;
private String connectionProviderDisablesAutoCommit;
private String connectionProvider;
private String connectionProviderClass;
private String connectionProviderDisablesAutoCommit;
private String connectionProvider;
private String connectionProviderClass;
// getter和setter方法
}
// getter和setter方法
}
具体使用场景
1. 数据库查询构建器
// SQL查询构建器
public class SqlQueryBuilder {
private StringBuilder query = new StringBuilder();
private List<Object> parameters = new ArrayList<>();
public SqlQueryBuilder select(String... columns) {
query.append("SELECT ");
if (columns.length == 0) {
query.append("*");
} else {
query.append(String.join(", ", columns));
}
return this;
}
public SqlQueryBuilder from(String table) {
query.append(" FROM ").append(table);
return this;
}
public SqlQueryBuilder where(String condition, Object... params) {
query.append(" WHERE ").append(condition);
for (Object param : params) {
parameters.add(param);
}
return this;
}
public SqlQueryBuilder and(String condition, Object... params) {
query.append(" AND ").append(condition);
for (Object param : params) {
parameters.add(param);
}
return this;
}
public SqlQueryBuilder or(String condition, Object... params) {
query.append(" OR ").append(condition);
for (Object param : params) {
parameters.add(param);
}
return this;
}
public SqlQueryBuilder orderBy(String column, String direction) {
query.append(" ORDER BY ").append(column).append(" ").append(direction);
return this;
}
public SqlQueryBuilder limit(int count) {
query.append(" LIMIT ").append(count);
return this;
}
public SqlQuery build() {
return new SqlQuery(query.toString(), parameters);
}
}
// 使用示例
public class SqlQueryBuilderDemo {
public static void main(String[] args) {
SqlQuery query = new SqlQueryBuilder()
.select("id", "name", "email")
.from("users")
.where("age > ?", 18)
.and("status = ?", "active")
.orderBy("name", "ASC")
.limit(10)
.build();
System.out.println("SQL: " + query.getSql());
System.out.println("Parameters: " + query.getParameters());
}
}
2. HTTP请求构建器
// HTTP请求构建器
public class HttpRequestBuilder {
private String method;
private String url;
private Map<String, String> headers = new HashMap<>();
private Map<String, String> queryParams = new HashMap<>();
private String body;
private int timeout = 5000;
public HttpRequestBuilder get(String url) {
this.method = "GET";
this.url = url;
return this;
}
public HttpRequestBuilder post(String url) {
this.method = "POST";
this.url = url;
return this;
}
public HttpRequestBuilder put(String url) {
this.method = "PUT";
this.url = url;
return this;
}
public HttpRequestBuilder delete(String url) {
this.method = "DELETE";
this.url = url;
return this;
}
public HttpRequestBuilder header(String name, String value) {
this.headers.put(name, value);
return this;
}
public HttpRequestBuilder queryParam(String name, String value) {
this.queryParams.put(name, value);
return this;
}
public HttpRequestBuilder body(String body) {
this.body = body;
return this;
}
public HttpRequestBuilder timeout(int timeout) {
this.timeout = timeout;
return this;
}
public HttpRequest build() {
return new HttpRequest(method, url, headers, queryParams, body, timeout);
}
}
// 使用示例
public class HttpRequestBuilderDemo {
public static void main(String[] args) {
HttpRequest request = new HttpRequestBuilder()
.post("https://api.example.com/users")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer token123")
.queryParam("page", "1")
.queryParam("size", "10")
.body("{\"name\":\"John\",\"email\":\"john@example.com\"}")
.timeout(10000)
.build();
System.out.println("Method: " + request.getMethod());
System.out.println("URL: " + request.getUrl());
System.out.println("Headers: " + request.getHeaders());
System.out.println("Query Params: " + request.getQueryParams());
System.out.println("Body: " + request.getBody());
System.out.println("Timeout: " + request.getTimeout());
}
}
3. 配置对象构建器
// 配置对象构建器
public class DatabaseConfig {
private final String host;
private final int port;
private final String database;
private final String username;
private final String password;
private final int maxConnections;
private final int timeout;
private final boolean ssl;
private DatabaseConfig(Builder builder) {
this.host = builder.host;
this.port = builder.port;
this.database = builder.database;
this.username = builder.username;
this.password = builder.password;
this.maxConnections = builder.maxConnections;
this.timeout = builder.timeout;
this.ssl = builder.ssl;
}
public static class Builder {
private String host = "localhost";
private int port = 3306;
private String database;
private String username;
private String password;
private int maxConnections = 10;
private int timeout = 30000;
private boolean ssl = false;
public Builder host(String host) {
this.host = host;
return this;
}
public Builder port(int port) {
if (port <= 0 || port > 65535) {
throw new IllegalArgumentException("端口号必须在1-65535之间");
}
this.port = port;
return this;
}
public Builder database(String database) {
if (database == null || database.trim().isEmpty()) {
throw new IllegalArgumentException("数据库名不能为空");
}
this.database = database;
return this;
}
public Builder username(String username) {
if (username == null || username.trim().isEmpty()) {
throw new IllegalArgumentException("用户名不能为空");
}
this.username = username;
return this;
}
public Builder password(String password) {
this.password = password;
return this;
}
public Builder maxConnections(int maxConnections) {
if (maxConnections <= 0) {
throw new IllegalArgumentException("最大连接数必须大于0");
}
this.maxConnections = maxConnections;
return this;
}
public Builder timeout(int timeout) {
if (timeout <= 0) {
throw new IllegalArgumentException("超时时间必须大于0");
}
this.timeout = timeout;
return this;
}
public Builder ssl(boolean ssl) {
this.ssl = ssl;
return this;
}
public DatabaseConfig build() {
if (database == null) {
throw new IllegalStateException("数据库名不能为空");
}
if (username == null) {
throw new IllegalStateException("用户名不能为空");
}
return new DatabaseConfig(this);
}
}
// getter方法
public String getHost() { return host; }
public int getPort() { return port; }
public String getDatabase() { return database; }
public String getUsername() { return username; }
public String getPassword() { return password; }
public int getMaxConnections() { return maxConnections; }
public int getTimeout() { return timeout; }
public boolean isSsl() { return ssl; }
}
面试高频点
面试知识点思维导图
1. 建造者模式的基本概念
问题:什么是建造者模式?
答案要点:
- 将复杂对象的构建过程分离出来,使得同样的构建过程可以创建不同的表示
- 属于创建型设计模式
- 通过一步步的构建过程创建复杂对象
- 封装构建逻辑,提高代码的可维护性
问题:建造者模式有哪些角色?
答案要点:
- Product(产品类):要构建的复杂对象
- Builder(抽象建造者):定义构建产品各个部分的抽象接口
- ConcreteBuilder(具体建造者):实现抽象建造者接口,构建和装配产品的各个部分
- Director(指挥者):调用建造者对象创建产品实例
- Client(客户端):使用指挥者创建产品
2. 实现方式相关
问题:如何实现建造者模式?
答案要点:
// 1. 定义产品类
public class Computer {
private String cpu;
private String memory;
// ... 其他属性
// getter和setter方法
}
// 2. 定义抽象建造者
public abstract class ComputerBuilder {
protected Computer computer = new Computer();
public abstract void buildCpu();
public abstract void buildMemory();
// ... 其他构建方法
public Computer getComputer() {
return computer;
}
}
// 3. 实现具体建造者
public class GamingComputerBuilder extends ComputerBuilder {
@Override
public void buildCpu() {
computer.setCpu("Intel i7-12700K");
}
@Override
public void buildMemory() {
computer.setMemory("32GB DDR4");
}
// ... 其他实现
}
// 4. 定义指挥者
public class ComputerDirector {
private ComputerBuilder builder;
public ComputerDirector(ComputerBuilder builder) {
this.builder = builder;
}
public Computer construct() {
builder.buildCpu();
builder.buildMemory();
// ... 其他构建步骤
return builder.getComputer();
}
}
3. 重难点问题
问题:建造者模式与工厂模式的区别?
答案要点:
- 目的:建造者模式关注构建过程,工厂模式关注对象创建
- 复杂度:建造者模式用于构建复杂对象,工厂模式用于创建简单对象
- 灵活性:建造者模式更灵活,可以自定义构建过程
- 使用场景:建造者模式用于复杂对象构建,工厂模式用于对象创建
问题:如何实现链式调用的建造者模式?
答案要点:
// 链式调用建造者模式
public class Computer {
private String cpu;
private String memory;
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.memory = builder.memory;
}
public static class Builder {
private String cpu;
private String memory;
public Builder setCpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder setMemory(String memory) {
this.memory = memory;
return this;
}
public Computer build() {
return new Computer(this);
}
}
}
// 使用示例
Computer computer = new Computer.Builder()
.setCpu("Intel i7-12700K")
.setMemory("32GB DDR4")
.build();
4. Spring中的应用
问题:Spring中如何使用建造者模式?
答案要点:
// 1. SpringApplicationBuilder
SpringApplication app = new SpringApplicationBuilder()
.sources(Application.class)
.profiles("dev")
.web(WebApplicationType.SERVLET)
.build();
// 2. HttpSecurity
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
5. 设计原则相关
问题:建造者模式体现了哪些设计原则?
答案要点:
- 单一职责:建造者只负责构建过程
- 开闭原则:可以添加新的建造者类型
- 依赖倒置:依赖抽象而不是具体实现
- 接口隔离:客户端只依赖需要的接口
6. 实际应用场景
问题:建造者模式适用于哪些场景?
答案要点:
- 复杂对象构建:需要多个步骤构建的复杂对象
- 配置对象:需要灵活配置的对象
- 查询构建器:SQL查询、HTTP请求等构建器
- 链式调用:需要链式调用的场景
- 参数验证:需要在构建过程中验证参数
使用总结
建造者模式的优势
- 分离构建过程:将复杂对象的构建过程与表示分离
- 灵活配置:可以灵活配置对象的各个部分
- 代码复用:同样的构建过程可以创建不同的表示
- 易于维护:构建逻辑封装在建造者中,易于维护
- 链式调用:支持链式调用,提高代码可读性
建造者模式的缺点
- 复杂度增加:增加了系统的复杂度
- 代码冗余:需要创建多个建造者类
- 内存开销:建造者对象会占用额外内存
- 学习成本:需要理解建造者模式的概念
使用建议
- 复杂对象:只用于构建复杂对象,简单对象不需要使用
- 参数较多:当构造函数参数较多时,考虑使用建造者模式
- 链式调用:优先使用链式调用的建造者模式
- 参数验证:在构建过程中添加参数验证
- 线程安全:多线程环境下注意线程安全
最佳实践
- 使用静态内部类:将Builder作为静态内部类
- 参数验证:在build()方法中进行参数验证
- 链式调用:所有setter方法都返回this
- 不可变对象:构建的对象应该是不可变的
- 文档注释:为建造者方法添加详细的文档注释
建造者模式是一种非常有用的设计模式,特别适用于构建复杂对象的场景。通过合理使用建造者模式,可以大大提高代码的可读性、可维护性和灵活性。
1223

被折叠的 条评论
为什么被折叠?



