还有这种操做?浅析为何要看源码

前言

不少人都有一个疑惑,为何面试都喜欢问原理,问源码.可是实际工做根本用不上,也就是你们常说的,面试造火箭,进去拧螺丝.我身边也有很多朋友问过我,我给他们的回答是.若是不看源码,不懂原理,出了问题你怎么解决?他们给个人答复基本都是两个字,"搜索"面试

也确实,工做中大部分问题经过复制错误信息搜索都能解决,加上如今框架愈来愈多,拼积木式的编程方式加上搜索引擎,让愈来愈多人产生了开发是件很容易的事的错觉.我也一直想举一个搜索几乎搜不到,要看源码才能弄懂其中原因的例子.编程

图片

正巧这件事发生在了去年8月份,我一个很好的朋友问了我这么个问题,他说设计模式

为何我传的是空字符串,可是用Mybatis的if标签判断该空字符串 == 0 居然是成立的浏览器

从咱们的认知上来讲,一个 空字符串 和 一个数字0 是不可能相等的.因此我第一反应是,他是否是用法不对?或者是他的业务代码其余地方干扰到了? 因而我决定写了个最简单的demo来进行测试.以下mybatis

而后输出结果以下:app

惊奇的发现,这个if标签果真把空字符串数字0判断成了相等.框架

这里我并不想骗你们,遇到这种问题,坦白说第一反应固然不是看源码啦,固然是打开浏览器搜索一下.咱们搜索的方向主要有两个,一个是mybatis if标签的判断原理,一个是为何mybatis if标签空字符串和0是相等的.结果发现,并无找到咱们要想的答案(你们能够自行搜索一下).ide

固然虽然没有搜索到满意的答案,可是咱们却发现了另外一个例子.测试

我相信相似这种判断的代码你们项目中应该出现了不少.ui

1<if test="uid != null and uid != '' ">
2</if>

咱们平时开发中,不少同事都是喜欢复制黏贴!

那么不假思索的复制黏贴到底会有什么问题呢,咱们来看下面这个例子

这个判断虽然是复制黏贴一把梭出来的,可是从咱们的认知上来讲,这个对象确实不是null,也不等于空字符串,因此这个判断应该是true的,可是运行结果以下:

果真,这个又颠覆了咱们的认知,可是若是你遇到的是案例2这种状况还比较好搜索,仍是能搜到解决方案,以下图

其实这两个案例都是一个问题,那就是这个if标签,把0和空字符串判断成了相等.

这个时候要敲黑板划重点了,俗话说一朝被蛇咬十年怕井绳,虽然第二个例子咱们有了解决方案,可是这些解决方案都是治标不治本,若是咱们没弄懂这其中的原理,那么你内心永远是有一块疙瘩的.你惧怕下一次,又有奇奇怪怪的事情发生,只有弄懂原理,才能从根源解决问题,也就是解决一类问题,而不是某一个问题.

同时我也认识到,机会来了,终于找到一个为何要看源码的比较合适例子了

分析源码

因为链路比较长.这里就不把debug过程展现了(对Mybatis执行流程不熟悉的,能够看看我以前的别怕看源码,一张图搞定Mybatis的Mapper原理,而后顺着执行流程debug)

咱们拿第一个例子来分析,由于两个案例其实遇到的问题都是同样的.





若是上面看不懂,我这里能够简单描述一下:

首先他会获取两个判断对象的类型,当拿一个字符串和一个数字判断的时候,由于类型不同嘛,当mybatis发现,这个字符串是能够转换成数字的,那么就会把这个字符串转成数字,而后再和这个数字判断.

那么问题就来了,这个空字符串会转换成什么数字呢?

从源码的这个

1return s.length() == 0 ? 0.0D : Double.parseDouble(s);

就能够看出,这个空字符串,是会被转成0的.因此如今一切豁然开朗.

可是源码是看了,问题仍是没有解决啊.他里面其余类型判断的源码这么多,不可能所有看完,时间也不容许啊,万一还有其余坑怎么办.因而可知,只看源码仍是不够的,还须要一些解决问题的分析思路,这就是为何网上源码解析的文章这么多,咱们还要关注一下肥朝的博客^_^

解决问题的思路

咱们虽然看了源码,咱们也知道了这个判断的规则和咱们想要的,是有出入的.可是关键是,怎么解决问题嘛.不少人第一反应是,那就修改源码呗.可是坦白说,你只看了这么一小片源码就贸然修改,肯定能驾驭得住,肯定不会引起其余问题?因此这个解决问题的思考方向,注意,我说的是方向,是很是重要的.

若是说到面向对象的三大特性,那么你们想必都不会陌生.封装继承多态.可是面向对象的五大原则.那么你们可能就稍微要陌生了.那就是

  • 单一职责

  • 开闭原则

  • 依赖致使原则

  • 接口隔离原则

  • Liskov替换原则

那我就说一下开闭原则,引用一下百度知道里面比较简短的描述是这样的

开放封闭原则,其核心思想是:软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。

若是你对设计模式有所了解的话,就很能了解这句话的意义.若是对这个不理解的,能够看一下大话设计模式这种书中,是如何引入策略设计模式的.简单的说是这样的,若是你是用if判断,那么多增长一个需求,你就要多增长一个else if,那就是要修改代码了.可是好的设计应该是,多增长一个需求,我只须要多增长一个实现类,也就是一种策略.(若是还不清楚的同窗,建议看看设计模式),其实SPI,也是包含这种开闭原则的思想的.

Mybatis这么优秀的框架.人家天然明白面向对象的五大原则,因此一定会遵循这个原则.也就是说,他必定会提供一个方式,让你多增长一个类,而后这个类里面,来自定义这个if的判断规则.

解决方案

咱们自定义一个类,就好比我取名为FeiChaoOgnl

图片

而后咱们的写法变成这样

图片

那么咱们运行看看

图片

图片

只要把FeiChaoOgnl判断方法补充完整,按照这个写法,就算是复制黏贴一把梭,出问题的风险也大大下降

写在最后

其实只要认准了解决问题的方向,那么解决问题,天然是水到渠成的事.这个解决问题的思路,才是本篇内容最具备核心价值的地方.我以前的源码解析文章,都在不断灌输原理,分析思路.一样的,这篇也不会例外.由于我想告诉你们的是一个解决问题的思路,是一个一通百通的分析方法.而不只仅是某一个问题的解决方案.这也是肥朝博客的初心,我也但愿可以一直作到不忘初心.

鉴于肥朝才疏学浅,文中不足之处还望你不吝斧正.

相关文章
相关标签/搜索