宽泛的来说,定义某个类针对某个对象进行构建,这个类就可以叫做创建者,该方式就可以叫做创建者模式。

一、创建者模式在 JDK 中的应用

JDK 中关于创建者模式的典型应用有 StringBuilder StringBuffer ,不过这两种实现方式是一样,唯一的区别在于一个加了同步锁,一个没加锁。

以 StringBuilder 为例进行创建者模式的剖析。

首先 StringBuilder 是一个创建者,而 StringBuilder 要构建的对象就是字符串。

字符串可以直接使用 String 对象,然后使用 “+” 运算符进行新对象的构建拼接,为什么还需要使用创建者模式来构建字符串?

首先单从字符串构建复杂度出发,如果需要拼接的内容较多,使用 “+” 明显会影响代码可读性,除此之外 “+” 每一次字符串的拼接都会产生新的字符串对象,对性能有一定影响。

再来看一下 StringBuilder 关键代码逻辑

[设计模式]-[创建型]-创建者-应用实例 - 图1

通过 **char[]** 字符数组来存储字符串,最后通过 **toString** 将数组转换为字符串。而 char[] 数据有方法 append() 来进行填充。

在整个构建模型中,构建的属性只有一个 char[] ,充当数据set的就是 append() 方法,最后进行对象构建的就是 toString() 方法。

二、Spring中的创建者模式

在 SpringFramework 中,所有 Bean 在实例化前都是以 BeanDefinition 的结构定义存在,而本身 BeanDefinition 的构建是很复杂的,感兴趣可以自己看一下 springframework 关于 BeanDefinition 的抽象实现

**org.springframework.beans.factory.support.AbstractBeanDefinition** 以及相关子类实现,针对复杂的对象构建 Springframework 使用了创建者的模式来进行实现,实现类为 **BeanDefinitionBuilder**

来看一下 **BeanDefinitionBuilder** 相关代码实现

[设计模式]-[创建型]-创建者-应用实例 - 图2

BeanDefinitionBuilder 符合创建者模式的特征

1、对象的构建复杂,包括 set的复杂操作
2、在最后进行实例化时,会有流程判断 Beandefinition 的属性设置完整性校验等。

三、Mybatis 中的创建者模式

3.1、XMLConfigBuilder

在 Mybatis 框架中 Configuration 可以说是贯穿整个上下文重要的对象,而 Configuration 的构建信息,需要通过解析响应的配置文件获取,操作流程的复杂可想而知,
Mybatis 采用创建者模式通过 XMLConfigBuilder 屏蔽了所有复杂构建流程,用户在使用过程直接使用 API 即可获取到的 Configuration 对象。

[设计模式]-[创建型]-创建者-应用实例 - 图3

3.2、CacheBuilder

在 Mybatis 中使用装饰者模式实现了缓存功能,可以在基础缓存实现 PerpetualCache 的基础附加各种功能,如:线程安全,FIFO策略,LRU 策略,周期性缓存等。

对此 Mybatis 提供了 CacheBuilder 用来进行缓存的构建,相关代码如下:

[设计模式]-[创建型]-创建者-应用实例 - 图4

CacheBuilder 符合创建者模式的定义,屏蔽了复杂对象的构建,用户需要什么样的缓存,只需要通过 true or false ,要还是不要,最后通过 build() 即可获取到具有相应功能的缓存
而无需理解 Cache 如何实现,如何构建对象。

四、JetCache 中的创建者模式

JetCache 是 阿里 开源的缓存项目,在项目中针对缓存对象的构建同样适用的创建者模式来完成,来看一下 **AbstractCacheBuilder** 相关代码

[设计模式]-[创建型]-创建者-应用实例 - 图5

AbstractCacheBuilder 符合创建者模式的定义,

五、项目中 Builder 模式的使用

通过 Builder 能够实现链式编程,使得代码更简洁,同样也可以屏蔽对象构建的流程。

比如:在封装第三方 API 时使用 Builder 的方式来构建请求链接,以微信用户 AccessToken 获取请求URL拼接为例:

微信用户请求凭证 accessToken 获取需要的参数对应的对象如下:

[设计模式]-[创建型]-创建者-应用实例 - 图6

API 构建者代码实现如下:

[设计模式]-[创建型]-创建者-应用实例 - 图7

代码使用效果

[设计模式]-[创建型]-创建者-应用实例 - 图8

首先是链式编码风格,整个代码清爽直观,
其次就是屏蔽了url的拼接,以及参数名称从驼峰到下划线的转换(微信 API参数命令方式为下划线,自己项目中字段名为驼峰类型)


【公众号】花好夜猿
wxlogo.jpg