Builder Pattern,将一个复杂对象的构建和它的表现分离,使得同样的构建过程可以创建不同的表示。
The Builder design pattern is a creational design pattern, designed to provide a flexible design solution to various object creation problems in Object-Oriented software. The intent of the Builder design pattern is to separate the construction of a complex object from its representation. It is one of the GoF design patterns.
The Builder design pattern solves problems like:
1、How can a class (the same construction process) create different representations of a complex object?
2、How can a class that includes creating a complex object be simplified?
参考
Java创建对象(重叠构造器模式,javaBean模式,Builder模式)
创建对象的方式
1、构造器模式
参数较多时,代码难看,可读性差。
2、javabean 模式
通过构造器,生成对象,后面根据 set 方法来给对象赋值。 容易造成线程不安全,对象处于不一致状态。类无法仅仅通过检验构造器参数的有效性来保证一致性。
3、build 模式
调用构造器生成 build 对象,然后在 build 对象上类似 set 方法来设置每个相关的可选参数;最后调用 build() 方法生成不可变的对象。
DataSourceBuilder 实例
public class DataSourceBuilder {
private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] {
"org.apache.tomcat.jdbc.pool.DataSource",
"com.zaxxer.hikari.HikariDataSource",
"org.apache.commons.dbcp.BasicDataSource", // deprecated
"org.apache.commons.dbcp2.BasicDataSource" };
private Class<? extends DataSource> type;
private ClassLoader classLoader;
private Map<String, String> properties = new HashMap<String, String>();
public static DataSourceBuilder create() {
return new DataSourceBuilder(null);
}
public static DataSourceBuilder create(ClassLoader classLoader) {
return new DataSourceBuilder(classLoader);
}
public DataSourceBuilder(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public DataSource build() {
Class<? extends DataSource> type = getType();
DataSource result = BeanUtils.instantiate(type);
maybeGetDriverClassName();
bind(result);
return result;
}
private void maybeGetDriverClassName() {
if (!this.properties.containsKey("driverClassName")
&& this.properties.containsKey("url")) {
String url = this.properties.get("url");
String driverClass = DatabaseDriver.fromJdbcUrl(url).getDriverClassName();
this.properties.put("driverClassName", driverClass);
}
}
private void bind(DataSource result) {
MutablePropertyValues properties = new MutablePropertyValues(this.properties);
new RelaxedDataBinder(result).withAlias("url", "jdbcUrl")
.withAlias("username", "user").bind(properties);
}
public DataSourceBuilder type(Class<? extends DataSource> type) {
this.type = type;
return this;
}
public DataSourceBuilder url(String url) {
this.properties.put("url", url);
return this;
}
public DataSourceBuilder driverClassName(String driverClassName) {
this.properties.put("driverClassName", driverClassName);
return this;
}
public DataSourceBuilder username(String username) {
this.properties.put("username", username);
return this;
}
public DataSourceBuilder password(String password) {
this.properties.put("password", password);
return this;
}
@SuppressWarnings("unchecked")
public Class<? extends DataSource> findType() {
if (this.type != null) {
return this.type;
}
for (String name : DATA_SOURCE_TYPE_NAMES) {
try {
return (Class<? extends DataSource>) ClassUtils.forName(name,
this.classLoader);
}
catch (Exception ex) {
// Swallow and continue
}
}
return null;
}
private Class<? extends DataSource> getType() {
Class<? extends DataSource> type = findType();
if (type != null) {
return type;
}
throw new IllegalStateException("No supported DataSource type found");
}
}
复制代码
初始化代码:
DataSourceBuilder.create()
.url("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=true&allowMultiQueries=true")
.username("root")
.password("root")
.driverClassName("com.mysql.jdbc.Driver")
.build());
复制代码