Builder Pattern (创建对象)

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模式)

Java build模式

在构造过程中JavaBeans可能处于不一致的状态

创建对象的方式

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());
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值