復(fù)用的著相
著相是佛家用語(yǔ),指的是執(zhí)著于外相偏離了本質(zhì)。
仙劍奇?zhèn)b傳中有一個(gè)故事。講的是一個(gè)成精了的佛珠。想要讓更多的人向佛,于是施法,讓這些人失去了記憶,只想一心禮佛。使人向佛,本來(lái)是好事,但強(qiáng)人所難,脫離了本質(zhì),便是著了相,也可以說(shuō)反而是入了魔。
這個(gè)小故事告訴我們,在認(rèn)知的世界里,我們很容易被表象所欺騙,忽略了本質(zhì)。為此,佛家發(fā)明了這么一個(gè)名詞來(lái)專門指出這種現(xiàn)象。
復(fù)用也是一樣。復(fù)用本來(lái)是通過(guò)消除重復(fù)的方式。得到一系列可以復(fù)用的組件。從而在未來(lái)的開發(fā)工作中,更快速的響應(yīng)需求變化,也就是所謂的提升響應(yīng)力。
然而很多復(fù)用的結(jié)果,會(huì)造成代碼是變少了,改起來(lái)卻更難了。復(fù)用是增加了,可讀性卻下降了??紤]到軟件開發(fā)是一個(gè)團(tuán)隊(duì)協(xié)作的工作,而我們這個(gè)行業(yè)的離職率又能到百分之二十之多。難以學(xué)習(xí)的代碼確實(shí)是難以維護(hù)的,盡管你可以抱怨接手的人無(wú)能,但總之是降低了響應(yīng)力,也就違背了復(fù)用的本質(zhì)。
什么情況下會(huì)出現(xiàn)這樣的場(chǎng)景呢?主要是因?yàn)橐暯堑膯我?,只從自己?jiǎn)我坏囊暯强吹搅酥貜?fù)而不是在做全局優(yōu)化。這個(gè)說(shuō)法可能稍微有些抽象,那我說(shuō)幾個(gè)相對(duì)具體的情況。
當(dāng)我們只關(guān)注功能視角的時(shí)候
需求有很多的描述視角,可以只在功能角度描述,比如“網(wǎng)站要有任務(wù)卡,任務(wù)卡上有文字版學(xué)習(xí)內(nèi)容,視頻講解、也有作業(yè)題。”也可以加入業(yè)務(wù)視角,比如“學(xué)生要報(bào)名特訓(xùn)營(yíng),才能參加特訓(xùn)營(yíng)。學(xué)生進(jìn)入特訓(xùn)營(yíng)后,就看到了任務(wù)卡列表。學(xué)生在任務(wù)卡上閱讀學(xué)習(xí)資料,閱讀完學(xué)習(xí)資料后做題來(lái)驗(yàn)證他是否學(xué)到,做完后提交交由助教審閱。”當(dāng)我們只看功能視角的時(shí)候,可能會(huì)忽視業(yè)務(wù)上的不同,變的在功能角度過(guò)分抽象,***當(dāng)業(yè)務(wù)變化的時(shí)候,反而響應(yīng)速度比較弱。
一個(gè)簡(jiǎn)單的后臺(tái),我們看起來(lái)所有東西長(zhǎng)得都一樣,不過(guò)是列表頁(yè)面,添加頁(yè)面修改頁(yè)面,再加點(diǎn)兒刪除什么的功能。說(shuō)穿了都是crud,干脆我把這事弄成一一個(gè)組件好了,每個(gè)頁(yè)面只需要簡(jiǎn)單配置一下,就可以出來(lái)自己的一套增刪改查頁(yè)面。
這種視角完全沒(méi)有考慮到,不同的實(shí)體,它們其實(shí)所在的業(yè)務(wù)是不一樣的,關(guān)心它們的人也是不一樣的。***,彼此的演化方向也總會(huì)出現(xiàn)一些不同,你把它定義成一種東西,對(duì)于我每做一個(gè)修改,都要背負(fù)著其他所有實(shí)體的特異性。于是就逐漸拖慢了我改變的速度,降低了響應(yīng)能力。
無(wú)謂的自動(dòng)化
有追求的程序員一定會(huì)考慮提升工作效率,通過(guò)一些自動(dòng)化的手段來(lái)縮短流程,提高效率。不過(guò)有時(shí)候,這種追求也會(huì)有害。
在我們的系統(tǒng)里有一個(gè)面包屑功能,就是典型的“頁(yè)面A / 頁(yè)面B / 頁(yè)面C”那種面包屑。團(tuán)隊(duì)成員提出,一個(gè)個(gè)頁(yè)面寫面包屑好煩啊,干脆做一個(gè)根據(jù)URL生成面包屑的功能吧。乍一看好像提高了效率,但實(shí)際上URL上的名詞和你想顯示在面包屑上的名字是可能出現(xiàn)不同的。
比如在我們的場(chǎng)景里,我們提供一個(gè)任務(wù)卡的預(yù)覽功能,你的面包屑可能是“xx后臺(tái) / xx 訓(xùn)練營(yíng)管理界面 / xx卡預(yù)覽”,而學(xué)生正式使用任務(wù)卡的時(shí)候,他可能是 “ 學(xué)習(xí)中心 / xx 訓(xùn)練營(yíng) / xx卡 ”。而他們的url里可能都會(huì)出現(xiàn)'/programs/$pid/tasks/$tid'。同樣的program、task翻譯出來(lái)的文字完全不同。你為了支持這點(diǎn)不同,又要擴(kuò)展一些額外功能來(lái)做這種區(qū)分,做來(lái)做去,可能還不如直接寫來(lái)的方便,至多抽幾個(gè)常量來(lái)簡(jiǎn)單的消除一下重復(fù)。
當(dāng)我們只從代碼上看重復(fù)性的時(shí)候
這個(gè)我就不舉例子了,其實(shí)很多犯這個(gè)錯(cuò)誤的人都是重構(gòu)的支持者,不過(guò)學(xué)藝不太精。因?yàn)槿绻阕屑?xì)看的話,重構(gòu)里好多懷味道都有一個(gè)跟他對(duì)立的懷味道,比如發(fā)散式變化和霰彈式修改。如果我們只看代碼就會(huì)違背復(fù)用的本質(zhì)——更好的響應(yīng)變化。
這個(gè)跟我說(shuō)的***個(gè)場(chǎng)景,只關(guān)注功能視角是類似的問(wèn)題,這個(gè)可能更具象一點(diǎn),只關(guān)注代碼。
無(wú)視上下文的時(shí)候
這個(gè)可以看作是只有功能視角的一種情況,很多功能我們覺(jué)得有重復(fù)性,提升成一個(gè)概念,然而其實(shí)根本是兩個(gè)東西,他們只是剛好叫一個(gè)名字。
比如過(guò)去很多軟件里,是有一個(gè)統(tǒng)一的用戶組概念,不管你在哪個(gè)業(yè)務(wù)上下文里,你都需要擴(kuò)展這個(gè)用戶組的概念來(lái)管理用戶的權(quán)限。這個(gè)帶來(lái)的結(jié)果就是用戶組變得越來(lái)越臃腫,每次修改都要改一下別的組的功能。在我們的網(wǎng)校數(shù)字平臺(tái)里,學(xué)生學(xué)習(xí)有學(xué)習(xí)小組,老師出題有出題小組,這兩個(gè)小組業(yè)務(wù)完全不一樣,這個(gè)時(shí)候如果都用統(tǒng)一的用戶組來(lái)管理的話,那就勢(shì)必會(huì)造成無(wú)謂的耦合,損害響應(yīng)力。
這些故事告訴我們,我們不是在真空里去做復(fù)用。我們做的軟件都是有它的商業(yè)目的。我們的工程實(shí)踐也都是為商業(yè)目的服務(wù)的。當(dāng)我們說(shuō)tech@core的時(shí)候,讓我們說(shuō)技術(shù)就是業(yè)務(wù)的時(shí)候。誠(chéng)然,他給技術(shù)人員帶來(lái)了更多的權(quán)利,然而權(quán)利越大,責(zé)任也越大。技術(shù)人員也需要跳出技術(shù),具備更多的業(yè)務(wù)視角和體驗(yàn)視角。而不僅僅是沉浸在技術(shù)得自high當(dāng)中。才能真正的發(fā)揮出各種實(shí)踐的價(jià)值。
【本文是51CTO專欄作者“ThoughtWorks”的原創(chuàng)稿件,微信公眾號(hào):思特沃克,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】