服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

2万多行MyBatis源码,你知道里面用了多少种设计模式吗?

日期: 来源:脚本之家收集编辑:
 关注
“脚本之家
”,与百万开发者在一起

文末包邮送书!!!

在MyBatis的两万多行的框架源码中,使用了大量的设计模式对工程架构中的复杂场景进行解耦,这些设计模式的巧妙使用是整个框架的精华。

经过整理,大概有以下设计模式,如图1所示。

图1

01

类型:创建型模式

工厂模式

SqlSessionFactory 的结构如图2所示。

图2

工厂模式:简单工厂是一种创建型模式,在父类中提供一个创建对象的方法,允许子类决定实例对象的类型。

场景介绍:SqlSessionFactory 是获取会话的工厂,每次使用MyBatis 操作数据库时, 都会开启一个新的会话。在会话工厂的实现中,SqlSessionFactory 负责获取数据源环境配置信息、构建事务工厂和创建操作SQL 的执行器,最终返回会话实现类。

同类设计:SqlSessionFactory、ObjectFactory、MapperProxyFactory 和DataSourceFactory。

单例模式

Configuration 单例配置类的结构如图3所示。

图3

单例模式:是一种创建型模式,能够保证一个类只有一个实例,并且提供一个访问该实例的全局节点。

场景介绍:Configuration 是一个大单例,贯穿整个会话周期,所有的配置对象(如映射、缓存、入参、出参、拦截器、注册机和对象工厂等)都在Configuration 配置项中初始化, 并且随着SqlSessionFactoryBuilder 构建阶段完成实例化操作。

同类场景:ErrorContext、LogFactory 和Configuration。

建造者模式

ResultMap 建造者模式的结构如图4所示。


图4

建造者模式:使用多个简单的对象一步一步地构建成一个复杂的对象,提供了一种创建对象的最佳方式。

场景介绍:建造者模式在MyBatis 中使用了大量的XxxxBuilder,将XML 文件解析到各类对象的封装中,使用建造者及建造者助手完成对象的封装。它的核心目的是不希望把过多的关于对象的属性设置写到其他业务流程中,而是用建造者方式提供最佳的边界隔离。

同类场景:SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XML StatementBuilder 和CacheBuilder。


02

类型:结构型模式

适配器模式

日志实现类的结构如图5所示。

图5

适配器模式:是一种结构型模式,能使接口不兼容的对象也可以相互合作。

场景介绍:正是因为有太多的日志框架,包括Log4j、Log4j2 和Slf4J 等,而这些日志框架的使用接口又各有差异,为了统一这些日志框架的接口,MyBatis 定义了一套统一的接口,为所有的其他日志框架的接口做相应的适配。

同类场景:主要集中在对Log 日志的适配上。

代理模式

代理模式的实现结构如图6所示。

图6

代理模式:是一种结构型模式,能够提供对象的替代品或占位符。代理控制元对象的访问,并且允许在将请求提交给对象前进行一些处理。

场景介绍:没有代理模式就不存在各类框架。就像MyBatis 中的MapperProxy 实现类, 代理工厂实现的功能就是完成DAO 接口的具体实现类的方法,配置的任何一个DAO 接口调用的CRUD 方法,都会被MapperProxy 接管,调用到方法执行器等,并返回最终的数据库执行结果。

同类场景:DriverProxy、Plugin、Invoker 和MapperProxy。

组合模式

解析节点类的结构如图7所示。

图7

组合模式:是一种结构型模式,可以将对象组合成树形结构以表示“部分—整体” 的层次结构。

场景介绍:在MyBatis XML 动态的SQL 配置中,共提供了9 种标签(trim、where、set、foreach、if、choose、when、otherwise 和bind),使用者可以组合出各类场景的SQL 语句。而SqlNode 接口的实现就是每个组合结构中的规则节点,通过规则节点的组装,完成规则树组合模式的使用。

同类场景:主要体现在对各类SQL 标签的解析上,以实现SqlNode 接口的各个子类为主。

装饰器模式

二级缓存装饰器的实现结构如图8所示。

图8

装饰器模式:是一种结构型设计模式,允许将对象放入包含行为的特殊封装对象中, 为元对象绑定新的行为。

场景介绍:MyBatis 的所有SQL 操作都是经过SqlSession 调用SimpleExecutor 完成的, 而一级缓存的操作也是在简单执行器中处理的。这里的二级缓存因为是基于一级缓存刷新的,所以在实现上,通过创建一个缓存执行器,包装简单执行器的处理逻辑,实现二级缓存操作。这里用到的就是装饰器模式,也叫俄罗斯套娃模式。


03

类型:行为型模式

模板模式

SQL 执行模板模式如图9所示。

图9

模板模式:是一种行为型模式,在超类中定义了一个算法的框架,允许子类在不修改结构的情况下重写算法的特定步骤。场景介绍:存在一系列可被标准定义的流程,并且流程的步骤大部分采用通用逻辑,只有一小部分是需要子类实现的,通常采用模板模式来定义这个标准的流程。就像MyBatis 的BaseExecutor 就是一个用于定义模板模式的抽象类,在这个类中把查询、修改的操作都定义为一套标准的流程。

同类场景:BaseExecutor、SimpleExecutor 和BaseTypeHandler。

策略模式

多类型处理器策略模式的结构如图10所示。

图10

策略模式:是一种行为型模式,能定义一系列算法,并将每种算法分别放入独立的类中,从而使算法的对象能够互相替换。

场景介绍:在MyBatis 处理JDBC 执行后返回的结果时,需要按照不同的类型获取对应的值,这样就可以避免大量的if 判断。所以,这里基于TypeHandler 接口对每个参数类型分别做了自己的策略实现。

同类场景:PooledDataSource、UnpooledDataSource、BatchExecutor、ResuseExecutor、SimpleExector、CachingExecutor、LongTypeHandler、StringTypeHandler 和DateTypeHandler。

迭代器模式

拆解字段解析实现的结构如图11所示。

图11

迭代器模式:是一种行为型模式,能在不暴露集合底层表现形式的情况下遍历集合中的所有元素。

场景介绍:PropertyTokenizer 用于MyBatis 的MetaObject 反射工具包下,用来解析对象关系的迭代操作。这个类在MyBatis 中使用得非常频繁,包括解析数据源配置信息并填充到数据源类上,同时参数的解析、对象的设置都会使用这个类。

同类场景:PropertyTokenizer。

04

总结

通过梳理,MyBatis大约运用了10种左右设计模式。可以说,复杂且优秀的ORM 框架源码在设计和实现的过程中都会使用大量的设计模式。

在解决复杂场景的问题时,需要采用分治、抽象的方法,运用设计模式和设计原则等相关知识,把问题合理切割为若干子问题,以便加以理解和解决。

学习源码远不是只是为了应付面试,更重要的是学习优秀框架在复杂场景下的解决方案。通过学习这些优秀的方案技术,可以提高对技术设计和实现的理解,扩展编码思维,积累落地经验。只有经过这样长期的积累,我们才更有可能成为优秀的高级工程师和架构师。

本文节选自《手写MyBatis:渐进式源码实践》一书,欢迎阅读本书了解更多相关内容!

限时五折优惠,快快扫码抢购吧!

福利  ~

#留言有礼# 你对设计模式了解吗?有什么想说的?留言分享你的看法,或者宝贵学习经验

>>> 活动参与
活动截止时我们会抽取幸运小锦鲤获得《手写MyBatis:渐进式源码实践》纸质书籍一本。

特别申明:

1、一位用户1个月内只能有1次获奖机会,让更多粉丝受益活动才更有意义

2、每一位用户只有1次留言机会,不允许重复留言~

请大家记住这三个1

>>> 活动时间

活动截止时间:2023 年 03 月 03 日 16:00 整

兑奖截止时间:2023 年 03 月 04 日 16:00 整

点击阅读原文,查看本书详情!

相关阅读

  • 灵乡镇:回访教育暖人心 监督执纪唤初心

  • “感谢组织对我的关怀,我一定改正错误,时刻谨记党员身份,严格要求自己,不再靠近那些打牌的地方……”吴某林同志拉着灵乡镇纪委工作人员的手,诚恳地说道。原来,吴某林同志此前因聚
  • 智慧家庭好懂,三翼鸟难飞

  • 如果说15年前,“靠语音开灯”还是少数人炫耀的新鲜谈资,那么在2022年,就连小县城的普通家庭都已随处可见蓝牙音箱、扫地机器人、指纹门锁等单品。国人对智能家居的兴趣,已然支撑
  • 中国最神秘千亿独角兽,难解「砍一刀」

  • 被拼多多海外版“砍一刀”,SHEIN陷入增长焦虑?‍来源 |豹变(微信ID:baobiannews)作 者 | 佘伟航编 辑 | 邢 昀‍‍‍‍‍‍排 版 | 群 响供应链总部坐落在广州番禺城
  • 这波神了!国外超火の软件,国内直接用!

  • 大家好,我是你们的好朋友大明,欢迎大家来到【大明青年】。今日分享最近大家是不是在各平台上都能看到Chātgpt的热搜呢,确实挺火的,很多人也一直问国内有没有,国内要怎么使用。今
  • 手把手带你搞懂AMS启动原理

  • / 今日科技快讯 /近日,加拿大政府以维护政府信息安全为由,宣布禁止在政府部门使用的移动设备上使用TikTok(抖音海外版)应用程序。按加官方要求,从2023年2月28日起,TikTok应用
  • 实现一个简单的 Spring Bean 容器

  • 面对复杂的源码,试着找到开头和结尾是一件非常具有挑战的事。为了让更多的初学者上手,从本文开始,我们将通过实践的方式带领读者逐步实现 Spring 框架的核心链路和功能逻辑。简
  • 一些顶级 JavaScript 技巧汇总

  • 英文 | https://medium.com/stackanatomy/top-javascript-shorthand-techniques-64920294f0c8JavaScript包含各种对典型编程思想有用的一些技巧,在实际开发中,我们通常希望减

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • 面试黑话翻译,听懂就是避坑

  • 关注“脚本之家”,与百万开发者在一起来源丨智联招聘(ID:zhaopin-com)作者 | 桃之窈窈如若转载请联系原公众号初入职场时,新人往往还没拿到薪资,便会先交一笔学费。这笔学费倒不
  • C++17一个很冷门很有意思的新特性

  • 关注“脚本之家”,与百万开发者在一起来源丨经授权转自 程序喵大人(ID:chengxumiaodaren)已获得原公众号授权转载最近发现了一个有意思的特性:void_t。void_t是C++17引入的一个