1.3 語言的抽象性
關(guān)于抽象思維,其定義如下:
抽象思維,又稱詞(概念)的思維,是指用詞(概念)進行判斷、推理并得出結(jié)論的過程。抽象思維以詞(概念)為中介來反映現(xiàn)實。這是思維的最本質(zhì)特征,也是人的思維和動物心理的根本區(qū)別。
之所以把抽象思維稱為詞思維或概念思維,是因為語言和抽象是一體的。我們只能通過語言表達抽象的概念,并進行邏輯判斷和推理。
當我們說牛的時候,說的就是牛的抽象,它代表了所有牛共有的特征。我在演講中分享抽象思維的時候,會經(jīng)常給同學(xué)們下套。
我問:“你見過牛嗎?”
同學(xué)說:“見過啊。”
我繼續(xù)問:“你確定你真的見過?!”
同學(xué)說:“好像——見過——吧——”
我繼續(xù)問:“在哪里見的?”
同學(xué)說:“在老家的山頭上。”
我說:“你沒有見過牛,你能看到的是那頭在老家山頭上正在吃草的老黃牛。而牛作為一個抽象概念,你既看不見也摸不著,它只存在于你的思維之中。”
當你在程序中創(chuàng)建牛(Cow)這個類(Class)的時候,道理也是一樣的,它代表了對一類牛的抽象。而每一個實例(instance)代表了一頭一頭具象的牛,比如那頭在山上吃草的老黃牛。
因為語言的抽象性,我在團隊中會要求大家使用通用語言(Ubiquitous Language)進行溝通交流,因為只有大家對概念的認知達成一致,溝通交流起來才會順暢,而程序只是我們程序員之間的一種交流方式。
這也是我在做設(shè)計和代碼審查(Code Review)的時候,會特別關(guān)注命名是否合理的原因。因為命名的好壞在很大程度上反映了我們對一個概念的思考是否清晰、抽象是否合理,反映在代碼上就是代碼的可讀性、可理解性是否良好,以及我們的設(shè)計是否到位。
有人做過一個調(diào)查,問程序員最頭疼的事情是什么。Quora和Ubuntu Forum的調(diào)查結(jié)果顯示,程序員最頭疼的事情是命名。如果你曾經(jīng)為了一個命名而絞盡腦汁,就不會對這個結(jié)果感到意外。
正如Stack Overflow的創(chuàng)始人Joel Spolsky所說:
“Creating good names is hard,but it should be hard,because a great name captures essential meaning in just one or two words.”(起一個好名字應(yīng)該很難,因為,一個好名字需要把要義濃縮在一到兩個詞中。)
這個濃縮的過程就是抽象的過程。我不止一次發(fā)現(xiàn),當我覺得一個地方的命名有些別扭的時候,往往就意味著要么這個地方我沒有思考清楚,要么是我抽象錯了。
關(guān)于如何命名,我在《代碼精進之路:從碼農(nóng)到工匠》[1]一書里已給出了比較詳盡的闡述,這里就不贅述了。
我想強調(diào)的是:語言是明晰概念的基礎(chǔ),也是抽象思維的基礎(chǔ),在構(gòu)建一個系統(tǒng)時,值得我們花很多時間去斟酌和推敲語言。我曾經(jīng)做過一個項目,在過程中針對一個關(guān)鍵實體討論了兩天,因為那是一個新概念,我們嘗試了很多名字,卻始終感覺別扭、不好理解。隨著討論和對問題域理解的深入,我們最終找到了一個相對比較合適的名字,才算罷休。
這樣的斟酌是有意義的,因為明晰關(guān)鍵概念是我們設(shè)計中的重要工作。雖然不合理的命名和不合理的抽象也能實現(xiàn)業(yè)務(wù)功能,但代價就是維護系統(tǒng)時的極高的認知負荷。隨著時間的推移,也許就沒人能搞懂系統(tǒng)為何這樣設(shè)計了。