一、构建者模式:
1、介绍:
建造者模式的定义是:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
2、建造者模式的角色定义:
一个构建者模式包含以下几个类:
- 导演类(Director):按照一定的顺序或者一定的需求去组装一个产品。
- 构造者类(builder+ConcreteBuilder):提供对产品的不同个性化定制,最终创建出产品。
其实他是:build接口+ConcreteBuilder接口实现类。正规的是先有一个接口builder,然后真正的构建是在实现类ConcreteBuilder中构建的。 - 产品类(Product):最终的产品。
3、工厂模式和构建者模式区别:
- 工厂模式构建出来的对象,其对象的属性都是一致的,即对象都是一样的。
- 构建者模式可以根基你的要求定制不同属性的对象。
4、为什么使用构建者模式?什么场景使用构建者模式?:
- 在mybatis框架中,对于构建者模式使用的比较频繁。
- 假如我们需要一个对象,一个对象的创建非常的复杂,对象中还要对象的封装,那么我们就可以使用构建者模式,将该对象的构建交给它来处理,我们使用的时候找他要一个对象就可以了。
- 我想要一个对象,工厂模式就会创建一个对象,该对象的属性是固定的几个;而构建者模式可以通过导演类,组合不同的属性或者成员,可以构建出不同的对象。
- 设计模式在实际的使用中使可以变化的,并不是固定的格式。
二、mybatis源码中-构建者模式解析:
1、MappedStatement的构建:
在mybatis中MapperBuilderAssistant类中对于MappedStatement对象的构建就是使用了构建者模式:
//利用构建者模式,去创建MappedStatement.Builder,用于创建MappedStatement对象
MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType)
.resource(resource)
.fetchSize(fetchSize)
.timeout(timeout)
.statementType(statementType)
.keyGenerator(keyGenerator)
.keyProperty(keyProperty)
.keyColumn(keyColumn)
.databaseId(databaseId)
.lang(lang)
.resultOrdered(resultOrdered)
.resultSets(resultSets)
.resultMaps(getStatementResultMaps(resultMap, resultType, id))
.resultSetType(resultSetType)
.flushCacheRequired(valueOrDefault(flushCache, !isSelect))
.useCache(valueOrDefault(useCache, isSelect))
.cache(currentCache);
// 通过MappedStatement.Builder,构建一个MappedStatement
MappedStatement statement = statementBuilder.build();
- 在上面代码中,有一系列的属性,比如:.resource(resource)、.fetchSize(fetchSize)等,导演类通过Buld定制不同的属性(组合不同的属性),最终会产生不同属性的对象。
- 定制完属性之后,通过下面的build()方法,产生不同的对象。该build()方法调用的是MappedStatement对象中的build方法
2、SqlSessionFactory的构建:
需求:
在mybatis中的通过SqlSessionFactoryBuilder类中通过build()方法构建SqlSessionFactory对象,该对象的构建就采用了构建者模式:
导演类: 按照一定的顺序或者一定的需求去组装SqlSessionFactory。
public class MybatisSqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
final MybatisConfiguration targetConfiguration;
final SqlSessionFactory sqlSessionFactory = new
MybatisSqlSessionFactoryBuilder().build(targetConfiguration);
}
}
构造者类:
下面是SqlSessionFactoryBuilder中build()方法:
产品类:
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
由构造器可以得知:产品类是DefaultSqlSessionFactory:
/**
* @author Clinton Begin
*/
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
@Override
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
}
可以通过调用不同的build()的方法(参数不一样),构造出符合自己的SqlSessionFactory对象,采用的是构建者模式。
三、自己编写一个构建者模式:
需求:通过构建者模式构建自己想要的对象,即产品。
1、导演类:
/**
* 导演类:测试类
*/
public class BuildDemo {
public static void main(String[] args) {
StudentBuild build = new StudentBuild();
// 决定如何创建一个Student
//构建产品一:
Student student1 = build.age(1).name("张三").father("张老大").build();
//构建产品二:
Student student2 = build.age(1).name("李四").build();
System.out.println(student);
}
}
2、构造者类:构建器:
/**
* 构造者类:构建器
*
* 注意:我们写的demo没有创建build接口,就直接使用实现类来实现构造这模式。
*/
public class StudentBuild {
/*
成员属性:需要构建的对象,直接new一个
*
*/
private Student student=new Student();
/**
* 下面是构造方法
*/
public StudentBuild id(int id){
student.setId(id);
return this;//返回的是StudentBuild对象
}
public StudentBuild name(String name){
student.setName(name);
return this;//返回的是StudentBuild对象
}
public StudentBuild age(int age){
student.setAge(age);
return this;//返回的是StudentBuild对象
}
public StudentBuild father(String fatherName){
Father father = new Father();
father.setName(fatherName);
student.setFather(father);
return this;//返回的是StudentBuild对象
}
/**
* 构建对象的方法:build方法
*/
public Student build(){
return student;//返回的是Student对象
}
}
3、产品类:
/**
* 产品类
*/
public class Student {
private int id;
private String name;
private int age;
//子产品
private Father father;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Father getFather() {
return father;
}
public void setFather(Father father) {
this.father = father;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", father=" + father +
'}';
}
}
//子产品类:
public class Father {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4、总结分析:
1、我们的需求是:采用构建者模式,构建出不同的产品。由上面代码的我们构建出了两个产品。
2、导演类其实就是我们的测试类,即调用build()方法的类。
3、构建者类:其实就是在一个类中,对不同的属性做了一个构造方法,然后,通过一个build()方法
导演类想要组合的属性组合到一起,然后通过build()方法构造出想要的对象。
4、产品类:就是我们最终想要构造的对象。
5、该demo能够直观的让我们理解构造者模式,但是模式不是固定的代码格式,是可以变换的,这一点要记住。