緣起
最近,因為多個因素綜合作用的情況下,我有幸得以負責一個專案的重構事項,並且時間/空間上都是相當寬鬆。而且由於系統較為複雜,需要對接多個業務開發部門,導致各種大需求小需求特別多,因此如果我程式碼設計得爛,那麼我就要面臨加班擦屁股的尷尬局面。這也導致了我不敢隨意寫爛程式碼,儘量避免各種『破窗效應』。因此想記錄一些比較雜碎的感想,基本上是想到哪寫到哪,不會注重文章的結構佈局。
物件導向仍然是主流的設計風格
這裡要理解什麼是物件導向,而不是去背教材中的『封裝,繼承,多型』。軟體開發本來就是講究實踐的東西,背教材是最沒用的。『封裝,繼承,多型』可能恰恰是最不重要的,重要的是這些:
- 什麼是『控制反轉』,什麼是『依賴注入』,除了在Spring/Angular這樣的框架中見到之外,對我們實際設計程式碼有什麼實際的啟示。
- 什麼是『SOLID』原則,有什麼實際啟示,哪些很容易做到,哪些看似容易實際上很難做到。
世界是有狀態的,導致我們的程式碼也是充滿了各種各樣的狀態
這其實是第一點的原因,大概也是物件導向風格流行的原因?各種各樣的,骯髒的狀態,可以讓其隱藏在一個又一個的class後面,從而限制其影響範圍。
什麼是『組合』,什麼是『組合優於繼承』
『組合優於繼承』,至今不知道是什麼意思,也沒有見到比較有說服力的答案。我感覺這句話很像『高內聚低耦合』這樣很正確但是沒有什麼實際作用的廢話。比如『裝飾器模式』是組合一個很經典的例子,OK,講完『裝飾器模式』之後,我大概懂了這個模式,但是我還是沒懂『組合優於繼承』這句話的具體意思。大概只能靠意會了吧?
『繼承』沒有那麼不堪,『多繼承』可能要避免
承接上一段。貌似總有人將『組合』與『繼承』對立起來,然後有選擇地舉幾個例子,說『繼承』哪哪不好,『組合』哪哪好,然後得出上面那句話的結論。這種文章一般犯了『倖存者偏差』的錯誤,一般也夾帶了很多私貨,沒有啥營養。
其實我倒覺得,沒有孰優孰劣,因為兩者只不過是兩種不同的手段而已,比如吃飯可以用刀叉,也可以用筷子,解決問題還是要看場景。繼承沒有大V們吹的那麼噁心,畢竟也是根據實際問題而發明的手段,總不能一點用處也沒有吧?簡單用用其實挺好的,也能重用很多程式碼。
但是Java有種特別不好的風氣,就是搞巨多class,然後設計很複雜的繼承(介面)關係,層層封裝,真實意圖往往隱藏在層層程式碼之後。更有甚者,幾乎每一個class都搞一個interface,美名其曰為擴充設計,其實是『過度工程』。這種風氣下來,讓人寫Java缺少快樂的感覺,我猜大V批判Java主要是指的這個吧。
反正我寫Java是挺快樂的,想到哪寫到哪,也不刻意搞很多interface,大不了到後期再提取interface就行了,反正現在的IDE工具都是這樣強大。
『設計模式』很有用
這個東西真是強求不得,如果是強行搞『設計模式』,基本死得很慘,還不如不搞。在專案重構的過程中,我主要使用了『工廠方法、模板方法』這幾個模式,搞出來的程式碼確實讓人感到賞心悅目。特別是『模板方法』模式,我們的業務過程中有太多場景適合這個模式了,我幾乎全部都使用了它,改起Bug來嗖嗖的。
OOP與FP
OOP懂一點,FP基本不懂,不懂得領域,就不隨意評論了。對於FP,我發現一點,就是總有人拿它和OOP進行類比,列舉出個OOP的幾個缺點和FP的幾個優點,然後將OOP批判一番,然後得出『FP更優』的結論。講真,計算機世界的很多概念和事物,是不適合用類比來理解的,就像人的食指和中指,在實際生活中,各自完成不同的功能,各司其職,從而使我們能完成各種各樣的動作。如果你硬是將其對立起來,有其一就不能有其二,這不扯淡嗎?OOP和FP同理,本來就是兩種不同場景下的手段,如果硬是將它們對立起來,得出個孰優孰劣的結論,反而沒有什麼意義。各司其職,融合著使用,才是解決之道。
分層思路
任何軟體都是分層的,分層可以顯著降低人腦思考的難度,從而設計更加大型的軟體。在這種語境下面,『模組化』『分層』等概念,基本上是某種概念的不同側重點,基本上是同一個意思。
但是分層也不能太細太碎太多,這樣基本走向了反面,帶來了累贅。『中庸之道』才是硬道理,得靠大量積累的實際經驗。
《重構》、《Clean Code》
兩本好書,很影響人。看了好幾遍了,每次看都有新的收穫,看得次數越多,逐漸地會吸收作者『只可意會不可言傳』的某些內容,:)。