文章目录
介绍
定义: 将一个复杂对象的构建与它的实现分离,使得同样的构建过程可以创建不同的实现。
它是将一个复杂的对象拆分成多个组件,然后一步一步构建生成。它将变与不变分离开来,不变的是产品的组成成分,变的是组成产品的各个组件(每个组成可以有多个不同的组件)。
建造者模式中的角色:
1.产品(Product):包含各个组件的复杂对象,由具体构建者来提供组件。
2.抽象建造者(Builder):包含创建各个组件的的抽象方法的接口
3.具体建造者(Concrete Builder):实现Builder,实现各个组件。
4.指挥者(director ):它按照一定顺序调用建造者中创建各个组件的方法来创建最终的产品。
实现
造房子。
类图
House类(产品类)
package com.jc.builder;/**
* @program: 设计模式
*
* @description:
*
* @author: Mr.Wang
*
* @create: 2021-06-14 11:08
**/
public class House {
private String basic;
private String wall;
private String wuDing;
public House() {
}
public House(String basic, String wall, String wuDing) {
this.basic = basic;
this.wall = wall;
this.wuDing = wuDing;
}
@Override
public String toString() {
return "House{" +
"basic='" + basic + '\'' +
", wall='" + wall + '\'' +
", wuDing='" + wuDing + '\'' +
'}';
}
public String getBasic() {
return basic;
}
public void setBasic(String basic) {
this.basic = basic;
}
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getWuDing() {
return wuDing;
}
public void setWuDing(String wuDing) {
this.wuDing = wuDing;
}
}
HouseBuilder类(抽象构造者类)
package com.jc.builder;
public abstract class HouseBuilder {
House house = new House();
protected abstract void buildBasic();
protected abstract void buildWall();
protected abstract void buildWuDing();
public House getHouse(){
return house;
}
}
SmallHouseBuilder(具体构造者类)
package com.jc.builder;/**
* @program: 设计模式
*
* @description:
*
* @author: Mr.Wang
*
* @create: 2021-06-14 11:11
**/
public class SmallHouseBuilder extends HouseBuilder {
@Override
public void buildBasic() {
house.setBasic("5米");
System.out.println("小房子打地基");
}
@Override
public void buildWall() {
house.setWall("5米");
System.out.println("小房子墙高5米");
}
@Override
public void buildWuDing() {
house.setWuDing("5平米");
System.out.println("小房子建屋顶");
}
}
BigHouseBuilder(具体构造者类)
package com.jc.builder;/**
* @program: 设计模式
*
* @description:
*
* @author: Mr.Wang
*
* @create: 2021-06-14 12:31
**/
public class BigHouseBuilder extends HouseBuilder {
@Override
public void buildBasic() {
house.setBasic("30米");
System.out.println("大房子打30米深地基");
}
@Override
public void buildWall() {
house.setWall("20米");
System.out.println("大房子墙高20米");
}
@Override
public void buildWuDing() {
house.setWuDing("100平米");
System.out.println("大房子屋顶100平");
}
}
Client
package com.jc.builder;
/**
* @program: 设计模式
* @description:
* @author: Mr.Wang
* @create: 2021-06-14 11:17
**/
public class Client {
public static void main(String[] args) {
HouseBuilderDirector director = new HouseBuilderDirector();
//建造小房子
director.setBuilder(new SmallHouseBuilder());
House smallHouse = director.buildHouse();
System.out.println("最终构建出来的房子:"+smallHouse);
//建造大房子
director.setBuilder(new BigHouseBuilder());
House bigHouse = director.buildHouse();
System.out.println("最终构建出来的房子:"+bigHouse);
}
}
打印结果
====开始造房子=====
小房子打地基
小房子墙高5米
小房子建屋顶
最终构建出来的房子:House{basic='5米', wall='5米', wuDing='5平米'}
====开始造房子=====
大房子打30米深地基
大房子墙高20米
大房子屋顶100平
最终构建出来的房子:House{basic='30米', wall='20米', wuDing='100平米'}
好:客户端不需要知道产品内部细节,将产品本身与它的创建过程解耦。各个具体建造者之间相互独立,后期拓展方便(如果要盖一个别墅的话,只需要让别墅的建造者继承继承抽象建造者,并且实现对应的方法即可),符合ocp原则。
不好:产品内部组件复杂,如果内部组件发生变化(多了一个组件,少了一个组件),则建造者也要修改,后期维护成本较大。
比如我们造房子这个栗子,如果在房子中加一个窗口和门。那么我们的所有具体建造者都要加上这一步操作,具体建造者少的话还可以理解,但是如果要很多的话,还是挺麻烦的。
在mybatis源码中的引用
在org.apache.ibatis.builder下有一个builder的包,包下有一堆Builder类
BaseBuilder父类,其他的XXXBuilder都是它的子类,BaseBuilder是抽象建造者,而XXXBuilder则是具体建造者。
产品类(Configuration 类)
public class Configuration {
protected Environment environment;
protected boolean safeRowBoundsEnabled;
protected boolean safeResultHandlerEnabled;
protected boolean mapUnderscoreToCamelCase;
protected boolean aggressiveLazyLoading;
protected boolean multipleResultSetsEnabled;
protected boolean useGeneratedKeys;
protected boolean useColumnLabel;
protected boolean cacheEnabled;
protected boolean callSettersOnNulls;
protected boolean useActualParamName;
protected boolean returnInstanceForEmptyRow;
protected String logPrefix;
protected Class<? extends Log> logImpl;
protected Class<? extends VFS> vfsImpl;
protected LocalCacheScope localCacheScope;
protected JdbcType jdbcTypeForNull;
protected Set<String> lazyLoadTriggerMethods;
protected Integer defaultStatementTimeout;
protected Integer defaultFetchSize;
protected ResultSetType defaultResultSetType;
protected ExecutorType defaultExecutorType;
protected AutoMappingBehavior autoMappingBehavior;
protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior;
protected Properties variables;
protected ReflectorFactory reflectorFactory;
protected ObjectFactory objectFactory;
protected ObjectWrapperFactory objectWrapperFactory;
protected boolean lazyLoadingEnabled;
protected ProxyFactory proxyFactory;
protected String databaseId;
protected Class<?> configurationFactory;
protected final MapperRegistry mapperRegistry;
protected final InterceptorChain interceptorChain;
protected final TypeHandlerRegistry typeHandlerRegistry;
protected final TypeAliasRegistry typeAliasRegistry;
protected final LanguageDriverRegistry languageRegistry;
protected final Map<String, MappedStatement> mappedStatements;
protected final Map<String, Cache> caches;
protected final Map<String, ResultMap> resultMaps;
protected final Map<String, ParameterMap> parameterMaps;
protected final Map<String, KeyGenerator> keyGenerators;
protected final Set<String> loadedResources;
protected final Map<String, XNode> sqlFragments;
protected final Collection<XMLStatementBuilder> incompleteStatements;
protected final Collection<CacheRefResolver> incompleteCacheRefs;
protected final Collection<ResultMapResolver> incompleteResultMaps;
protected final Collection<MethodResolver> incompleteMethods;
protected final Map<String, String> cacheRefMap;
public Configuration(Environment environment) {
this();
this.environment = environment;
}
抽象建造者(BaseBuilde类)
package org.apache.ibatis.builder;
public abstract class BaseBuilder {
protected final Configuration configuration;
protected final TypeAliasRegistry typeAliasRegistry;
protected final TypeHandlerRegistry typeHandlerRegistry;
public BaseBuilder(Configuration configuration) {
this.configuration = configuration;
this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
}
public Configuration getConfiguration() {
return this.configuration;
}
//省略好多代码........。。
}
}
BaseBuilder类里面的Configuration 类是产品,getConfiguration()获取我们的产品。
具体建造者(MybatisXMLConfigBuilder)
public class MybatisXMLConfigBuilder extends BaseBuilder {
public Configuration parse() {
if (this.parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
} else {
this.parsed = true;
//调用parseConfiguration
this.parseConfiguration(this.parser.evalNode("/configuration"));
return this.configuration;
}
}
//进行建造对Configuration中的每个属性进行赋值
private void parseConfiguration(XNode root) {
try {
this.propertiesElement(root.evalNode("properties"));
Properties settings = this.settingsAsProperties(root.evalNode("settings"));
this.loadCustomVfs(settings);
this.loadCustomLogImpl(settings);
this.typeAliasesElement(root.evalNode("typeAliases"));
this.pluginElement(root.evalNode("plugins"));
this.objectFactoryElement(root.evalNode("objectFactory"));
this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
this.reflectorFactoryElement(root.evalNode("reflectorFactory"));
this.settingsElement(settings);
this.environmentsElement(root.evalNode("environments"));
this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
this.typeHandlerElement(root.evalNode("typeHandlers"));
this.mapperElement(root.evalNode("mappers"));
} catch (Exception var3) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
}
}
}
所以这里大概的类图是这样

本文通过实例讲解了如何在Mybatis源码中使用建造者模式,介绍了产品类(Configuration)、抽象建造者(BaseBuilder)和具体建造者(如XMLConfigBuilder)的角色,展示了如何通过这种方式实现配置的灵活构建和解耦。



1101

被折叠的 条评论
为什么被折叠?



