To程序員:要寫出好代碼,你需要懂點兒“底層思維”
??點擊“博文視點Broadview”,獲取更多書訊

在阿里巴巴的晉升會議上,評委經(jīng)常會問:“你的成功可以復(fù)制嗎?”
我最初做評委時基本不會問這樣的問題,因為我認(rèn)為這樣的問題很虛,工作完成就行了,不需要那么多道理。
然而隨著時間的推移,我發(fā)現(xiàn)這的確是一個好問題。
因為它可以區(qū)分出你是碰巧把事情做對了,還是你具備了一直做對事情的能力,二者是有本質(zhì)區(qū)別的。碰巧做對,說明你的能力可能還不足,換一種情景,你就不一定能應(yīng)付。
因此,好的晉升制度不僅要考查成績,更重要的是考查能力。對從事腦力勞動的技術(shù)人員來說,“能力”主要指的是“思維能力”。
例如,我們都知道編程的時候命名很重要,也很難,可為什么會這樣呢?
如果要深挖其背后的原因,將是一個非常有趣的話題,甚至可以和哲學(xué)有關(guān)。
命名工作中暗含了抽象思維能力和語言哲學(xué),語言本身是抽象的符號,比如當(dāng)你說“花”的時候,指的并不是某一朵具體的玫瑰花、郁金香,而是花的抽象概念。一朵具體的花雖然看得見、摸得著,但總會有凋零消亡的時候,而“花”這個字作為精神實體將永不會消亡。所以,抽象的花和具體的花到底哪個才是本真呢?這是一個哲學(xué)問題。
拋開哲學(xué)爭論,就“花”這個字而言,它是提取了所有花的共性的抽象符號。命名之所以難,是因為你要經(jīng)歷一個提取共性、歸納要義,并賦予恰當(dāng)名稱的抽象思維過程。
因此,要想真正做好命名,除了要掌握一些命名技法,還需要更深層次的修煉——提升抽象思維能力。
在《西方哲學(xué)史》中,奧古斯丁說:“至于什么是時間,在沒人問我時,我非常清楚;可一旦要向別人解釋,我就有點糊涂了?!?/span>
對于抽象的概念也是如此,我們都知道,抽象思維是工程師最重要的思維能力。因為軟件設(shè)計是純思維的創(chuàng)造活動,軟件技術(shù)本質(zhì)上就是一門抽象的藝術(shù)。程序員每天都要動用抽象思維,對問題域進(jìn)行分析、歸納、綜合、判斷、推理等。
但到底什么是抽象思維?什么是抽象的層次性?如何運用抽象思維解決軟件中的問題?如何提升抽象思維能力?對于這些問題,并不是每個人都能說的清楚。
簡而言之,“抽”就是抽離,“象”就是具象。從字面上理解抽象,抽象的過程就是從“具象”事物中歸納共同特征,“抽取”得到一般化的概念的過程。英文的抽象——abstract,來自拉丁文abstractio,它的原意是排除、抽出。
為了更直觀地理解抽象,讓我們先來看一幅畢加索的畫。圖的左邊是一頭水牛,是具象的;右邊是畢加索的畫,是抽象的。

抽象牛只有幾根線條,不過這幾根線條是做了高度抽象之后的線條,過濾了水牛的絕大部分細(xì)節(jié),只保留了牛最本質(zhì)的特征,比如牛角、牛頭、牛鞭、牛尾巴等。這種對細(xì)節(jié)的舍棄使得“抽象牛”具有更好的泛化(Generalization)能力。可以說,抽象概念更接近問題的本質(zhì)。也就是說,所有的牛都逃不過這幾根線條。
回到畢加索的抽象畫,如果映射到面向?qū)ο缶幊?,抽象牛就是抽象類?/span>Abstract Class),代表了所有牛的抽象。抽象??梢员环夯筛嗟呐#热缢?、奶牛、牦牛等。每一種牛都代表了一類(Class)牛,對于每一類牛,我們可以通過實例化,得到一個具體的牛實例(Instance)。

從這個簡單的案例中,我們可以總結(jié)出抽象的3個特點。
第一,抽象是忽略細(xì)節(jié)的。抽象類是最抽象的,忽略的細(xì)節(jié)也最多,就像抽象牛,只是幾根線條而已。在代碼中,這種抽象既可以是抽象類,也可以是接口(Interface)。
第二,抽象代表了共同性質(zhì)。類代表了一組實例的共同性質(zhì),抽象類代表了一組類的共同性質(zhì)。對于上面的案例來說,共同性質(zhì)就是抽象牛的那幾根線條。
第三,抽象具有層次性。抽象層次越高,其內(nèi)涵越小、外延越大,也就是說它的含義越小、泛化能力越強。比如,牛就要比水牛的抽象層次更高,因為它可以表達(dá)所有的牛,水牛只是牛的一個種類。
對于程序員來說,對抽象層次的權(quán)衡是對我們設(shè)計能力的考驗,要根據(jù)業(yè)務(wù)的需要,選擇合理的抽象層次,既不能太高,也不能太低。
例如,現(xiàn)在要寫一個關(guān)于水果的程序,我們需要對水果進(jìn)行抽象,因為水果里面有紅色的蘋果,我們當(dāng)然可以建一個RedApple的類,但是這個抽象層次有點低,只能用來表達(dá)“紅色的蘋果”。假如來一個綠色的蘋果,你還得新建一個GreenApple類。
為了提升抽象層次,我們可以把RedApple類改成Apple類,讓顏色變成Apple的屬性,這樣紅色和綠色的蘋果就都能用Apple表達(dá)了。再繼續(xù)往上抽象,我們還可以得到水果類、植物類等。

可以看出,抽象層次越高,內(nèi)涵越小,外延越大,泛化能力越強。然而,其代價就是業(yè)務(wù)語義表達(dá)能力越弱。
我經(jīng)常開玩笑說:“為了通用性,把所有的類都設(shè)置為Object,把所有的參數(shù)都設(shè)置為Map的系統(tǒng),是最通用的?!币驗镺bject和Map的內(nèi)涵最小,其泛化能力最強,可以適配所有的擴展。從原理上來說,這種抽象也是對的,萬物皆對象嘛!但我們?yōu)槭裁床贿@么做呢?就是因為越抽象,越空洞,雖然通用,但也“無用”。
思考一下,我們在寫代碼的過程中,什么時候會用到強制類型轉(zhuǎn)換呢?當(dāng)然是LSP不能被滿足的時候,也就是說子類的方法超出了父類的類型定義范圍,為了使用子類的方法,只能使用類型強制轉(zhuǎn)換將類型轉(zhuǎn)成子類類型。
舉個例子,在蘋果(Apple)類上,有一個isSweet()方法用于判斷水果甜不甜;在西瓜(Watermelon)類上,有一個isJuicy()用于判斷水分是否充足的;同時,它們都共同繼承一個水果(Fruit)類。
此時,我們需要挑選出甜的水果和有水分的西瓜,會編寫如下一段程序:
public class FruitPicker {public ListpickGood(List {fruits) return fruits.stream().filter(e -> check(e)).collect(Collectors.toList());}private boolean check(Fruit e) {if(e instanceof Apple){if(((Apple) e).isSweet()){return true;}}if(e instanceof Watermelon){if(((Watermelon) e).isJuicy()){return true;}}return false;}}
對于代碼中的強制類型轉(zhuǎn)換,仔細(xì)分析一下,可以發(fā)現(xiàn),根本原因在于isSweet()和isJuicy()的抽象層次不夠。站在更高的抽象層次,也就是Fruit的視角看,我們挑選的就是可口的水果,只是具體到蘋果時,我們看甜度;具體到西瓜時,我們看水分而已。
解決方法是對isSweet( )和isJuicy( )進(jìn)行抽象層次提升,我們可以在Fruit上創(chuàng)建一個isTasty( )的抽象方法。
注意:tasty這個詞本身就要比sweet和juicy要抽象。
因此,我們在做抽象提升的時候,一定是伴隨著語言的變化的。

通過提升抽象層次,我們消除了instanceof判斷和強制類型轉(zhuǎn)換,讓代碼重新滿足了里氏替換原則,利用面向?qū)ο蟮亩鄳B(tài),也使代碼重新變得優(yōu)雅可擴展了。
public class FruitPicker {public ListpickGood(List {fruits) return fruits.stream().filter(e -> check(e)).collect(Collectors.toList());}private boolean check(Fruit e) {return e.isTasty(); //不再需要instanceof和強制類型轉(zhuǎn)換}}
所以,每當(dāng)我們在程序中準(zhǔn)備使用instanceof做類型判斷,或者用cast做強制類型轉(zhuǎn)換的時候,都有可能是一次做提升抽象層次的機會。
本文節(jié)選自《程序員的底層思維》一書,想要了解更多相關(guān)內(nèi)容,歡迎閱讀本書!


▊ 《程序員的底層思維》
張建飛 著
這是一本超越具體編程技法的技術(shù)書:職場晉升不僅需要技術(shù)能力,更重要的是思維能力。本書帶你學(xué)會用底層思維解決復(fù)雜技術(shù)問題,突破職場“天花板”。
這也是一本培養(yǎng)思維能力的通用技能書:打破認(rèn)知局限,培養(yǎng)通用的思維能力。本書幫你跳出思維定勢,輕松解決生活及工作中遇到的問題。
本書涵蓋程序員應(yīng)知應(yīng)會的16種思維能力,共18章,分為三部分。
第一部分主要介紹抽象思維、邏輯思維、結(jié)構(gòu)化思維、批判性思維、維度思維、分類思維、分治思維、簡單思維,以及成長型思維等解決日常問題的基礎(chǔ)思維能力。
第二部分結(jié)合軟件行業(yè)的特點,主要介紹解耦思維、契約思維、模型思維、工具化思維、量化思維、數(shù)據(jù)思維,以及產(chǎn)品思維等專業(yè)思維能力。
第三部分主要是對上述思維能力的綜合運用實踐。
粉絲專享六折優(yōu)惠,掃碼即購!

?
如果喜歡本文 歡迎?在看丨留言丨分享至朋友圈?三連 ?熱文推薦??
▼點擊閱讀原文,了解本書詳情~
