由 Mybatis 源码畅谈软件设计(一):序

京东云开发者
• 阅读 283

作者:京东保险 王奕龙

从接触软件开发以来,一直对写出优雅的代码抱有执念,工作半年时,偶然接触到《代码整洁之道》,爱不释手,一口气读完,并在很长的时间内践行其中的观点,但是在这践行期间缺少思考和复盘,更多的是一味地信奉和遵守其中的原则,写了不少当时自认为不错而现在回过头看可读性不好的“坏代码”。

后来在员工培训时,导师介绍 《Head First 设计模式》 是影响他最大的一本书。我花了个把月读完,才渐渐理解设计原则和设计模式,并在项目中实际应用。慢慢地,开始考虑怎么设计更好,怎么解耦,怎么复用,如何满足开闭原则等等,虽然也经历过硬用设计模式的情况,但是我觉得这段时间对写代码的能力提升很多。

再后来对代码整洁有了新的理解是在读《软件设计哲学(第二版)》,其中提到的关于如何“提高可读性,降低复杂性”的观点是我之前没有接触过的,后来在对业务接口重构和代码评审中实践了其中的原则。这给了我一种别样的感觉:写好代码不再是“炫技”,而是时刻考虑“这段代码这么写,它好读吗?”,始终站在读者的角度去思考,将需求引入的复杂度降到最低。

有时候我也在考虑一个问题:在系统迭代的过程中,新功能的引入和开发人员的更替都可能会导致复杂性增加,进而使系统可维护性和可扩展性降低。但我却很少看到有团队花精力关注这件事情,通常是永不停止的需求迭代,等复杂性积累到一定程度,无法再满足业务需求时选择重构,而重构时面对欠维护的代码,需要再投入大量人力梳理、评估和研发设计,并且重构时大规模改动也伴随着产生 Bug 的风险,如果没有详细的测试用例或者没有对业务熟悉的测试工程师,该风险还会变大。此外,在中文互联网社区内也很少看到有我们国人写出的关于如何设计程序或什么是好的程序的内容或书籍,在程序员内比较流行的依然是08年出版的《代码整洁之道》,不得不说其中的观点并没有与时俱进,而适宜当前开发环境的《软件设计哲学(第二版)》是近两年的书籍,限于没有中文版导致传播范围有限。那我能帮大家做一些相关的事情吗?因为我觉得即使是老外写的较好的内容,面向的第一手开发者依然是以英语为母语的,适用于英语语境下的原则可能放在国内开发环境下并不适用。但限于能力和经验,也许我并不能将此写的很好,也希望大家能做勘误和内容补充,即使最后它没有非常棒的内容,那么能为新人开发者提供一些经验,少走一些弯路也是好的吧?

本专栏的内容基于我的开发、重构经验和一些代码整洁相关的书籍,主要参考书籍我会一一放在文末,也推荐大家去读原书。但是限于不能以实际业务开发代码为例,我一直在考虑以什么内容来承载这些,最终决定以 Mybatis 源代码为支撑,首先因为它足够简单,再就是源码采用了极简代码的风格,大家能够在追随源码的过程中,了解何时方法应该被拆分以增加可读性,何时书写长代码也是合适的,此外,还有一点是源码中注释信息很少,希望大家能在源码的阅读过程中了对“代码自解释”有自己的认识。在源码解析过程中,我会提到一些设计模式和原则,但更重要的是 自己真正深入到每一行代码中去研究才能真正理解,好代码永远都是写出来的而不是看出来的。除了了解这些方法以外,最重要的是希望大家能在平时工作中多应用和交流,多多参加代码评审,阅读其他人的代码,因为在读别人的代码时,更容易发现其中可读性差的点。希望大家能写出整洁、易维护和易扩展的代码,并能从中获取到软件设计和软件开发的快乐。

Mybatis 源代码中提供了非常完整的单元测试,文章中流程均采用其中单测进行验证,大家可点击如下链接下载源代码。

在所有内容开展之前,我想先给大家铺垫一个设计原则,它也是《软件设计哲学》中提到的最让人眼前一亮的观点:坚持“深”模块设计,如下图所示:

由 Mybatis 源码畅谈软件设计(一):序

它会将每个模块看作一个矩形,矩形的面积代表模块提供的功能,顶部边缘代表模块公开出的接口,边缘长度代表接口的复杂性,越长接口越复杂。设计较好的模块会比较深,因为它在简单的接口后隐藏了许多功能,其内部的复杂性只有一小部分对开发者可见。坚持深模块设计也就意味着提供调用简单但功能强大的接口。

在接下来的内容中,请大家带着这个原则,并在阅读源码过程中时时考虑“这样设计够深吗?”,相信大家能对软件设计有更好的理解和认识。

巨人的肩膀

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
京东云开发者 京东云开发者
1个月前
由 Mybatis 源码畅谈软件设计(二):MappedStatement 和 SqlSource
作者:京东保险王奕龙本节我们来介绍org.apache.ibatis.mapping.MappedStatement(映射SQL语句声明的类),它是MyBatis框架中的一个核心类,也是向后不断学习Mybatis源码的基础。在这部分源码中,最值得关注的设计
京东云开发者 京东云开发者
3星期前
工作中对InheritableThreadLocal使用的思考
作者:京东保险王奕龙代码评审时,发现在线程池中使用InheritableThreadLocal上下文会使其中的线程变量失效,无法获取到预期的变量值,所以对问题进行了复盘和总结。1.先说结论InheritableThreadLocal只有在父线程创建子线程时
京东云开发者 京东云开发者
2星期前
由 Mybatis 源码畅谈软件设计(五):ResultMap 的循环引用
作者:京东保险王奕龙本节我们来了解Mybatis是如何处理ResultMap的循环引用,它的解决方案非常值得在软件设计中参考。另外作为引申,大家可以了解一下Spring是如何解决Bean的循环注入的。以单测org.apache.ibatis.submitt
京东云开发者 京东云开发者
2星期前
由 Mybatis 源码畅谈软件设计(九):“能用就行” 其实远远不够
作者:京东保险王奕龙到本节Mybatis源码中核心逻辑基本已经介绍完了,在这里我想借助Mybatis其他部分源码来介绍一些我认为在编程中能最快提高编码质量的小方法,它们可能比较细碎,希望能对大家有所启发。关于方法的长度和方法拆分之前我在读完《代码整洁之道》
美凌格栋栋酱 美凌格栋栋酱
10小时前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
京东云开发者 京东云开发者
3个月前
「软件设计哲学」于延保代码改造中的实践
作者:京东保险王奕龙本文主要给大家分享软件设计中的两个理念,为什么我称软件设计是“理念”而不是“方法”或“原则”呢?这个想法主要受《Aphilosophyofsoftwaredesign》的影响,它将软件设计称为“哲学”,而哲学本身没有严格的定论,同样地,
京东云开发者 京东云开发者
1个月前
为什么《程序员修炼之道》评分高达 9.1?
作者:京东保险王奕龙开始接触到《程序员修炼之道:通向务实的最高境界》这本书是在豆瓣图书的高分榜单上,它的评分高达9.1,其中有条蛮有意思的书评非常吸引我:“这本书我读过5遍信不信,每个字都磨出了感情...爱看技术书的程序员,看看可以往上走走;不爱看技术书的