建造者模式在Mybatis中的典型应用即SqlSessionFactoryBuilder,让我们来了解到底什么是建造者模式。
建造者模式
角色
- Builder(抽象建造者):它为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是buildPartX(),它们用于创建复杂对象的各个部件;另一类方法是getResult(),它们用于返回复杂对象。Builder既可以是抽象类,也可以是接口。
- ConcreteBuilder(具体建造者):它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
- Product(产品角色):它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。
- Director(指挥者):指挥者又称为导演类,它负责安排复杂对象的建造次序。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者Setter方法将该对象传入指挥者类中。
产品角色
public class Computer {
private String brand;
private String cpu;
private String mainBoard;
// 省略 getter, setter, toString
}
抽象建造者 builder
public abstract class Builder {
protected Computer computer = new Computer();
public abstract void buildBrand();
public abstract void buildCPU();
public abstract void buildMainBoard();
public Computer createComputer() {
return computer;
}
}
具体建造者 DellComputerBuilder,ASUSComputerBuilder,分别建造戴尔电脑和华硕电脑
public class DellComputerBuilder extends Builder {
@Override
public void buildBrand() {
computer.setBrand("戴尔电脑");
}
@Override
public void buildCPU() {
computer.setCpu("i5-8300H 四核");
}
@Override
public void buildMainBoard() {
computer.setMainBoard("戴尔主板");
}
}
public class ASUSComputerBuilder extends Builder{
@Override
public void buildBrand() {
computer.setBrand("华硕电脑");
}
@Override
public void buildCPU() {
computer.setCpu("Intel 第8代 酷睿");
}
@Override
public void buildMainBoard() {
computer.setMainBoard("华硕主板");
}
}
指挥者 ComputerDirector,指挥构建过程
public class ComputerDirector {
public Computer construct(Builder builder) {
// 逐步构建复杂产品对象
Computer computer;
builder.buildBrand();
builder.buildCPU();
builder.buildMainBoard();
computer = builder.createComputer();
return computer;
}
}
可以通过反射机制和配置文件配合,创建具体建造者对象
public class Test {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
ComputerDirector director = new ComputerDirector();
// 从数据库或者配置文件中读取具体建造者类名
Class c = Class.forName("com.designpattern.ASUSComputerBuilder");
Builder asusBuilder = (Builder) c.newInstance();
Computer asusComputer = director.construct(asusBuilder);
System.out.println(asusComputer.toString());
}
}
SqlSessionFactoryBuilder
典型代表是SqlSessionFactoryBuilder,在 SqlSessionFactoryBuilder 中构建 SqlSessionFactory 对象的过程是这样的,首先需要通过XMLConfigBuilder 对象读取并解析 XML 的配置文件,然后再将读取到的配置信息存入到 Configuration 类中,然后再通过 build方法生成我们需要的DefaultSqlSessionFactory对象。
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
//调用下面的build方法构建
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}