定义
建造者模式(Builder Pattern),也称构建者模式,使用多个简单的对象一步一步构建成一个复杂的对象。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
应用实例:
1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的“套餐”;
2、Java 中的 StringBuilder。
类比分析
一般来说,如果一个对象的构建比较复杂,超出了构造函数所能包含的范围,就可以使用工厂模式 和 Builder 模式,相对于工厂模式会产出一个完整的产品,Builder 应用于更加 复杂的对象的构建,甚至只会构建产品的一个部分,直白来说,就是使用多个简单的对象一步一步构建成一个复杂的对象。
示例剖析
例子 1:使用构建者设计模式来生产 computer
1、将需要构建的目标类分成多个部件(电脑可以分为主机、显示器、键盘、音箱等部件);
2、 创建构建类;
3、 依次创建部件;
4、 将部件组装成目标对象。
例子 2:Mybatis 中的体现,SqlSessionFactory 的构建过程
Mybatis 的初始化工作非常复杂,不是只用一个构造函数就能搞定的。所以使用了建造者模式,使用了大量的 Builder,进行分层构造,核心对象 Configuration 使用了 XmlConfigBuilder 来进行构造。
在 Mybatis 环境的初始化过程中,SqlSessionFactoryBuilder 会调用 XMLConfigBuilder 读取所有的 MybatisMapConfig.xml 和所有*Mapper.xml 文件,构建 Mybatis 运行的核心对象 Configuration 对 象,然后将该 Configuration 对象作为参数构建一个 SqlSessionFactory 对象。
private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first //解析<properties />标签 propertiesElement(root.evalNode("properties")); // 解析 <settings /> 标签
Properties settings = settingsAsProperties(root.evalNode("settings")); //加载自定义的VFS实现类
loadCustomVfs(settings);
// 解析 <typeAliases /> 标签 typeAliasesElement(root.evalNode("typeAliases"));
//解析<plugins />标签
pluginElement(root.evalNode("plugins"));
// 解析 <objectFactory /> 标签
objectFactoryElement(root.evaINode("obj ectFactory"));
// 解析 <objectWrapper Factory /> 标签
obj ectWrappe rFacto ryElement(root.evalNode("objectWrapperFactory")); // 解析 <reflectorFactory /> 标签 reflectorFactoryElement(root.evalNode("reflectorFactory"));
// 赋值 <settings /> 到 Configuration 属性
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
// 解析 <environments /> 标签
environmentsElement(root.evalNode("environments"));
// 解析 <databaseIdProvider /> 标签 databaseldProviderElement(root.evalNode("databaseldProvider"));
}
其中 XMLConfigBuilder 在构建 Configuration 对象时,也会调用 XMLMapperBuilder 用于读取 *Mapper 文件, 而 XMLMapperBuilder 会使用 XMLStatementBuilder 来读取和 build 所有的 SQL 语句。
//解析<mappers />标签 mapperElement(root.evalNode("mappers"));
在这个过程中,有一个相似的特点,就是这些 Builder 会读取文件或者配置,然后做大量的 XpathParser 解析、配 置或语法的解析、反射生成对象、存入结果缓存等步骤,这么多的工作都不是一个构造函数所 能包括的,因此大量 采用了 Builder 模式来解决。
SqlSessionFactoryBuilder 类根据不同的输入参数来构建 SqlSessionFactory 这个工厂对象。