不少人都有一個疑惑,爲何面試都喜歡問原理,問源碼.可是實際工做根本用不上,也就是你們常說的,面試造火箭,進去擰螺絲.我身邊也有很多朋友問過我,我給他們的回答是.若是不看源碼,不懂原理,出了問題你怎麼解決?他們給個人答覆基本都是兩個字,"搜索"java
也確實,工做中大部分問題經過複製錯誤信息搜索都能解決,加上如今框架愈來愈多,拼積木式的編程方式加上搜索引擎,讓愈來愈多人產生了開發是件很容易的事的錯覺.我也一直想舉一個搜索幾乎搜不到,要看源碼才能弄懂其中原因的例子.面試
正巧這件事發生在了去年8月份,我一個很好的朋友問了我這麼個問題,他說編程
爲何我傳的是空字符串,可是用Mybatis的if標籤判斷該
空字符串 == 0
居然是成立的設計模式
從咱們的認知上來講,一個 空字符串
和 一個數字0
是不可能相等的.因此我第一反應是,他是否是用法不對?或者是他的業務代碼其餘地方干擾到了? 因而我決定寫了個最簡單的demo來進行測試.以下瀏覽器
而後輸出結果以下:mybatis
驚奇的發現,這個if標籤
果真把空字符串
和數字0
判斷成了相等.app
這裏我並不想騙你們,遇到這種問題,坦白說第一反應固然不是看源碼啦,固然是打開瀏覽器搜索一下.咱們搜索的方向主要有兩個,一個是mybatis if標籤的判斷原理,一個是爲何mybatis if標籤空字符串和0是相等的.結果發現,並無找到咱們要想的答案(你們能夠自行搜索一下).框架
固然雖然沒有搜索到滿意的答案,可是咱們卻發現了另外一個例子.測試
我相信相似這種判斷的代碼你們項目中應該出現了不少.ui
<if test="uid != null and uid != '' ">
</if>
複製代碼
咱們平時開發中,不少同事都是喜歡複製黏貼!
那麼不假思索的複製黏貼到底會有什麼問題呢,咱們來看下面這個例子
這個判斷雖然是複製黏貼一把梭出來的,可是從咱們的認知上來講,這個對象確實不是null
,也不等於空字符串
,因此這個判斷應該是true
的,可是運行結果以下:
果真,這個又顛覆了咱們的認知,可是若是你遇到的是案例2這種狀況還比較好搜索,仍是能搜到解決方案,以下圖
其實這兩個案例都是一個問題,那就是這個if標籤,把0和空字符串判斷成了相等.
這個時候要敲黑板劃重點了,俗話說一朝被蛇咬十年怕井繩,雖然第二個例子咱們有了解決方案,可是這些解決方案都是治標不治本,若是咱們沒弄懂這其中的原理,那麼你內心永遠是有一塊疙瘩的.你懼怕下一次,又有奇奇怪怪的事情發生,只有弄懂原理,才能從根源解決問題,也就是解決一類問題,而不是某一個問題.
同時我也認識到,機會來了,終於找到一個爲何要看源碼
的比較合適例子了
因爲鏈路比較長.這裏就不把debug過程展現了(對Mybatis執行流程不熟悉的,能夠看看我以前的別怕看源碼,一張圖搞定Mybatis的Mapper原理,而後順着執行流程debug
咱們拿第一個例子來分析,由於兩個案例其實遇到的問題都是同樣的.
若是上面看不懂,我這裏能夠簡單描述一下:
首先他會獲取兩個判斷對象的類型,當拿一個字符串和一個數字判斷的時候,由於類型不同嘛,當mybatis發現,這個字符串是能夠轉換成數字的,那麼就會把這個字符串轉成數字,而後再和這個數字判斷.
那麼問題就來了,這個空字符串會轉換成什麼數字呢?
從源碼的這個
return s.length() == 0 ? 0.0D : Double.parseDouble(s);
複製代碼
就能夠看出,這個空字符串,是會被轉成0的.因此如今一切豁然開朗.
可是源碼是看了,問題仍是沒有解決啊.他裏面其餘類型判斷的源碼這麼多,不可能所有看完,時間也不容許啊,萬一還有其餘坑怎麼辦.因而可知,只看源碼仍是不夠的,還須要一些解決問題的分析思路,這就是爲何網上源碼解析的文章這麼多,咱們還要關注一下肥朝的公衆號(id:feichao_java)
咱們雖然看了源碼,咱們也知道了這個判斷的規則和咱們想要的,是有出入的.可是關鍵是,怎麼解決問題嘛.不少人第一反應是,那就修改源碼唄.可是坦白說,你只看了這麼一小片源碼就貿然修改,肯定能駕馭得住,肯定不會引起其餘問題?因此這個解決問題的思考方向,注意,我說的是方向,是很是重要的.
若是說到面向對象的三大特性,那麼你們想必都不會陌生.封裝
、繼承
、多態
.可是面向對象的五大原則.那麼你們可能就稍微要陌生了.那就是
單一職責
開閉原則
依賴致使原則
接口隔離原則
Liskov替換原則
那我就說一下開閉原則
,引用一下百度知道里面比較簡短的描述是這樣的
開放封閉原則,其核心思想是:軟件實體應該是可擴展的,而不可修改的。也就是,對擴展開放,對修改封閉的。
若是你對設計模式有所瞭解的話,就很能瞭解這句話的意義.若是對這個不理解的,能夠看一下大話設計模式
這種書中,是如何引入策略
設計模式的.簡單的說是這樣的,若是你是用if
判斷,那麼多增長一個需求,你就要多增長一個else if
,那就是要修改代碼了.可是好的設計應該是,多增長一個需求,我只須要多增長一個實現類,也就是一種策略
.(若是還不清楚的同窗,建議看看設計模式),其實SPI,也是包含這種開閉原則的思想的.
Mybatis這麼優秀的框架.人家天然明白麪向對象的五大原則,因此一定會遵循這個原則.也就是說,他必定會提供一個方式,讓你多增長一個類,而後這個類裏面,來自定義這個if的判斷規則.
咱們自定義一個類,就好比我取名爲FeiChaoOgnl
而後咱們的寫法變成這樣
那麼咱們運行看看
只要把FeiChaoOgnl
判斷方法補充完整,按照這個寫法,就算是複製黏貼一把梭,出問題的風險也大大下降
本文僅爲冰山一角,上百篇原創乾貨還在路上,掃描下面二維碼關注肥朝,讓天生就該造火箭的你,再也不委屈擰螺絲!