什么是建造者模式?他在jdk、MyBatis源码怎么运用?( 二 )

这个类定义了5个方法 , 前面4个是产品类 , 实际开发中可以任意定义 , 相当于一个方法就是一个产品中的某一个部分 , 然后最后一个方法就是返回一个构建好的产品 。
3、建造者(ConcreteBuilder)创建一个实际的建造者角色类:
package com.zwx.design.pattern.builder.standard;import com.zwx.design.pattern.builder.Homework;/** * 建造者模式-具体建造者(ConcreteBuilder) */public class ConcreateBuilder extends HomeworkBuilder {private Homework homework;public ConcreateBuilder(Homework homework) {this.homework = homework;}@Overridepublic HomeworkBuilder buildEasyQc(String easyQc) {homework.setEasyQc(easyQc);return this;}@Overridepublic HomeworkBuilder buildNormalQc(String normalQc) {homework.setEasyQc(normalQc);return this;}@Overridepublic HomeworkBuilder buildMediumQc(String mediumQc) {homework.setEasyQc(mediumQc);return this;}@Overridepublic HomeworkBuilder buildHardQc(String hardQc) {homework.setEasyQc(hardQc);return this;}@Overridepublic Homework build() {return homework;}}这个类里面初始产品我们是通过构造器传进去 , 实际上也可以不传 , 通过其他方法初始化也是可以的 , 这个看需求或者个人喜好 。
注意:每个创建部分产品最后的返回值返回的都是this , 这样就可以实现链式写法 , 具体看下面的调用者写法
4、调用者(Director)最后调用者来创建产品
package com.zwx.design.pattern.builder.standard;import com.alibaba.fastjson.JSONObject;import com.zwx.design.pattern.builder.Homework;/** * 建造者模式-调用者(Director) */public class HomeworkDirector {public static void main(String[] args) {Homework homework = new Homework();HomeworkBuilder homeworkBuilder = new ConcreateBuilder(homework);homeworkBuilder.buildEasyQc("我是一道简单题目").buildNormalQc("我是一道标准难度题目").buildMediumQc("我是一道中等难度题目").buildMediumQc("我是一道高难度题目");homework = homeworkBuilder.build();System.out.println(JSONObject.toJSONString(homework));}}可以看到 , 这里不用和之前一样一行行去调用 , 直接通过链式写法一直往下build , 最终调用build()方法返回完整的产品对象 。
PS:很多地方的写法是把调用者根据不同组合封装起一个个方法供外界调用 , 这也是一种最严格标准的写法 , 只适合于排列组合较少结果的产品 。 如果有很多种搭配 , 还是目前这种写法比较合适 , 直接由使用者自己来选择搭配 。
适用场景建造者模式适用于一个具有较多的零件的复杂产品创建过程 , 而且产品的各个组成零件还会经常发生变化或者说需要支持动态变化 , 但是零件的种类却总体稳定的场景:

  • 1、相同的方法 , 不同的执行顺序需要产生不同的执行结果
  • 2、产品类非常复杂 , 调用不同的零件或者按照不同的顺序来组装产品后需要得到不同的产品
  • 3、当初始化一个对象非常复杂 , 而且很多参数都具有默认值
建造者模式在源码中体现建造者模式在源码中使用也很普遍:
  • 1、jdk源码中 , StringBuilder类,append方法就是给我们提供了一种链式创建对象的方法:

什么是建造者模式?他在jdk、MyBatis源码怎么运用?文章插图
然后toString方法返回了一个完整的对象:
什么是建造者模式?他在jdk、MyBatis源码怎么运用?文章插图
  • 2、MyBatis中SqlSessionFactoryBuiler中就用到了建造者模式 。

什么是建造者模式?他在jdk、MyBatis源码怎么运用?文章插图
上面就是构建一个SqlSessionFactory对象的方法 , 我们看到里面的XMLConfigBuilder其实就是一个具体建造者角色 , 而其父类BaseBuilder就是一个抽象建造者角色 。 下图就是BaseBuilder和其部分子类(为了方便截图 , 没有显示出所有子类):
什么是建造者模式?他在jdk、MyBatis源码怎么运用?文章插图
还有一种写法大家应该都非常熟悉的Example , 就是经典的链式写法build出来一个完整的sql语句 , 类似的还有Condition 。
什么是建造者模式?他在jdk、MyBatis源码怎么运用?文章插图
建造者模式优缺点建造者模式的优点有:
  • 1、封装性好 , 创建和使用分离
  • 2、扩展性好 , 建造类之间独立 , 一定程度上实现了解耦
建造者模式的缺点有:
  • 1、产生多余的Builder对象
  • 2、产品内部发生变化时 , 建造者都需要修改 , 成本较大
建造者模式和工厂模式区别建造者模式优点类似于工厂模式 , 都是用来创建一个对象 , 但是他们还是有很大的区别 , 主要区别如下: