還有這種操做?淺析爲何要看源碼

前言

不少人都有一個疑惑,爲何面試都喜歡問原理,問源碼.可是實際工做根本用不上,也就是你們常說的,面試造火箭,進去擰螺絲.我身邊也有很多朋友問過我,我給他們的回答是.若是不看源碼,不懂原理,出了問題你怎麼解決?他們給個人答覆基本都是兩個字,"搜索"面試

也確實,工做中大部分問題經過複製錯誤信息搜索都能解決,加上如今框架愈來愈多,拼積木式的編程方式加上搜索引擎,讓愈來愈多人產生了開發是件很容易的事的錯覺.我也一直想舉一個搜索幾乎搜不到,要看源碼才能弄懂其中原因的例子.編程

圖片

正巧這件事發生在了去年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判斷方法補充完整,按照這個寫法,就算是複製黏貼一把梭,出問題的風險也大大下降

寫在最後

其實只要認準瞭解決問題的方向,那麼解決問題,天然是水到渠成的事.這個解決問題的思路,纔是本篇內容最具備核心價值的地方.我以前的源碼解析文章,都在不斷灌輸原理,分析思路.一樣的,這篇也不會例外.由於我想告訴你們的是一個解決問題的思路,是一個一通百通的分析方法.而不只僅是某一個問題的解決方案.這也是肥朝博客的初心,我也但願可以一直作到不忘初心.

鑑於肥朝才疏學淺,文中不足之處還望你不吝斧正.

相關文章
相關標籤/搜索