剛學(xué)編程的時(shí)候有種想法,認(rèn)為難題應(yīng)該只解決一次。 但漸漸接觸多了前端開(kāi)發(fā),經(jīng)常要重復(fù)編寫(xiě)代碼,特別是生成頁(yè)面時(shí)。 是什么原因?qū)е铝舜a無(wú)法重用呢?
來(lái)看看大家是怎樣看待這個(gè)問(wèn)題的吧,也許會(huì)有所啟發(fā)。
Aa:主要的問(wèn)題在于,如果一個(gè)問(wèn)題你沒(méi)有去在不同的環(huán)境下解決很多遍,你很難分得清楚,哪個(gè)部分是通用的,哪個(gè)部分是跟你當(dāng)前的環(huán)境緊密相關(guān)的。如果你什么都不懂,你做出來(lái)的代碼當(dāng)然也沒(méi)辦法很好的被重用。所以問(wèn)題不可能只被解決一次,我們追求的只能是每一次解決的時(shí)候花的代價(jià)要更少,長(zhǎng)遠(yuǎn)來(lái)講趨向于0。
Ab:因?yàn)閺?fù)用并非無(wú)代價(jià),而且代價(jià)往往還很高。
從工程上說(shuō),任何特性都不是無(wú)代價(jià)的。復(fù)用提供了解決一類(lèi)問(wèn)題的靈活性,而靈活性作為一種功能,同樣有代價(jià)——正如過(guò)多地使用虛函數(shù)有性能損失,而過(guò)多地使用 interface 則一定程度上降低代碼可讀性。如果構(gòu)建靈活性的基石皆有代價(jià),那么我們不可能期望靈活性可以免費(fèi)獲得。
而所有的問(wèn)題解決之道本質(zhì)上都一樣:我們需要權(quán)衡每一個(gè)選擇的好處和壞處,做出對(duì)我們現(xiàn)在的項(xiàng)目最有利的方案。舉例來(lái)說(shuō):我們不會(huì)在項(xiàng)目最緊張的時(shí)候討論把業(yè)務(wù)邏輯抽取出來(lái)做一個(gè)通用的框架,原因很簡(jiǎn)單:時(shí)間不夠用。我們也不會(huì)在討論怎么設(shè)計(jì)通用框架的時(shí)候過(guò)多地討論我們具體項(xiàng)目的邏輯,因?yàn)樽非笸ㄓ眯缘脑O(shè)計(jì)目的導(dǎo)致我們不可能完全為某一個(gè)具體的業(yè)務(wù)優(yōu)化。
所以從這個(gè)意義上來(lái)說(shuō),阻礙代碼重用的最大原因,事實(shí)上來(lái)自項(xiàng)目自身:復(fù)用代碼在絕大多數(shù)情況下,都不是一個(gè)項(xiàng)目的最終目的。對(duì)任何項(xiàng)目來(lái)說(shuō),唯一絕對(duì)存在的目的,是在指定的時(shí)間內(nèi)完成客戶給出的需求。當(dāng)短期內(nèi)完成功能的需求和復(fù)用發(fā)生沖突時(shí),理智的項(xiàng)目管理者都不會(huì)選擇將注意力放在復(fù)用上。當(dāng)然,熱衷于復(fù)用的程序員必然會(huì)以長(zhǎng)遠(yuǎn)的好處為理由為復(fù)用辯護(hù);但正如前面的規(guī)則指出的,這依然是一個(gè)工程上的選擇問(wèn)題,因而仍然需要折衷。在遇到問(wèn)題時(shí),總是先倒向某一個(gè)結(jié)果再試圖解釋?zhuān)@不是折衷,而是預(yù)設(shè)立場(chǎng),這恰恰是工程的大忌。
至于第二個(gè)問(wèn)題,回答是:是的,對(duì)任何問(wèn)題只解決一次是理想狀態(tài),但重復(fù)解決三到五次問(wèn)題并非十惡不赦。客戶關(guān)心的是我們能不能解決他們的問(wèn)題,而不是能不能對(duì)任何問(wèn)題都只解決一次?!灰炎约旱男枨笳`以為是用戶的需求,這仍然是一個(gè)工程問(wèn)題。
Ac:可復(fù)用的東西(小到函數(shù),大到框架),一定是從諸多應(yīng)用場(chǎng)景中抽取出來(lái)的,換句話說(shuō),一定要先有場(chǎng)景,在場(chǎng)景達(dá)到一定數(shù)量一定復(fù)雜度之后才能抽象出來(lái)可復(fù)用的部分,也就是常說(shuō)的重構(gòu).一開(kāi)始就追求復(fù)用性沒(méi)什么意義,浪費(fèi)時(shí)間不說(shuō),更可能假象的場(chǎng)景根本就不存在,或者實(shí)際情況超過(guò)想象.一些老手們經(jīng)驗(yàn)足夠豐富,之前遇到過(guò)的問(wèn)題越多,在開(kāi)始設(shè)計(jì)的時(shí)候就能兼顧到更多的復(fù)用場(chǎng)景.做開(kāi)發(fā),成長(zhǎng)的幾個(gè)階段必不可少:
1. 不做設(shè)計(jì)(新手階段,能實(shí)現(xiàn)就好)
2. 過(guò)度設(shè)計(jì)(了解的東西多了,總想追求完美)
3. 簡(jiǎn)化設(shè)計(jì)(認(rèn)知逐漸深入,學(xué)會(huì)取舍)
4. 最優(yōu)設(shè)計(jì)(熟練掌握,知道概念適配場(chǎng)景)
其中23兩個(gè)狀態(tài)可能會(huì)往復(fù)多次,最終達(dá)到找到一個(gè)平衡的位置.
所以我覺(jué)得題主的狀態(tài)正是逐漸進(jìn)入過(guò)度設(shè)計(jì)的狀態(tài),想追求絕對(duì)的復(fù)用,沒(méi)什么不好,有想法就去實(shí)踐,讓結(jié)果來(lái)驗(yàn)證你的觀念,很多東西的度不是別人能教會(huì)的,是必須要親自體驗(yàn)才能了解的和掌握的.
Ad:重用的代碼,底層的好寫(xiě),上層的難寫(xiě)。
底層代碼抽象的是機(jī)器,服務(wù)的是程序員。程序員就那么點(diǎn)追求,讀寫(xiě)數(shù)據(jù),操作數(shù)據(jù),要快,要穩(wěn),要容易用,滿足就行了。
上層代碼抽象的是需求,服務(wù)的是用戶。用戶的需求各不相同,但每個(gè)人都覺(jué)得自己的需求特有道理,特正義。你說(shuō)這個(gè)我們做不到,因?yàn)橛昧薠X lib,立馬被噴。
那么多前端庫(kù)前仆后繼,折戟沉沙,卻又層出不窮,無(wú)非是因?yàn)槟承┬枨鬂M足不了。需求總在變,庫(kù)也跟著花樣翻新,但總是差了一兩步。說(shuō)到底,是什么阻止了重用?
是人心吶,是變幻莫測(cè)得人心。
人心是一個(gè) moving target,以固定的 pattern 來(lái)揣摩人心,結(jié)果就是一段想要解決十個(gè)需求,卻一個(gè)需求都解決不好的代碼。
所以,底層庫(kù)可以自頂向下的設(shè)計(jì);而面向客戶的代碼,還要以解決當(dāng)前問(wèn)題為先,等到類(lèi)似的問(wèn)題多了,再考慮重用。不要?jiǎng)傆龅揭粋€(gè)問(wèn)題,就想寫(xiě)個(gè)通用的解法,這樣的往往悲劇。
長(zhǎng)恨人心不如水,等閑平地起波瀾。
Ae:一句話介紹不清楚的,是因?yàn)閼卸琛?/p>
同樣的問(wèn)題應(yīng)該只解決三次。第一次,你怎么知道這段代碼能夠重用呢?第二次,也許只是巧合?第三次,看來(lái)這確實(shí)是個(gè)重復(fù)出現(xiàn)的問(wèn)題。然后你就該重構(gòu)以重用代碼了。
當(dāng)然還可能是因?yàn)槠珗?zhí)。重構(gòu)容易出一些很明顯的問(wèn)題,特別是當(dāng)你使用的語(yǔ)言類(lèi)型系統(tǒng)不夠強(qiáng)大而你又沒(méi)有足夠的測(cè)試的時(shí)候。這種時(shí)候,維護(hù)者通常的反應(yīng)是:重構(gòu)代碼首先放測(cè)試版,出了小問(wèn)題就修正,只要不是很難處理的大問(wèn)題一切好說(shuō)。但是遇到偏執(zhí)的維護(hù)者嘛,就只好放棄了: 放棄 you-get,轉(zhuǎn)投 youtube-dl。
Af:過(guò)早優(yōu)化是萬(wàn)惡之源。
編寫(xiě)代碼時(shí),對(duì)“可復(fù)用”和“擴(kuò)展性”的考慮,都應(yīng)限定在一個(gè)很小的范圍內(nèi)。否則的話,在當(dāng)前版本多消耗的時(shí)間要遠(yuǎn)遠(yuǎn)大于未來(lái)復(fù)用代碼時(shí)省下的時(shí)間。
從“編程藝術(shù)”的角度來(lái)講,這種解決方法一點(diǎn)都不漂亮。每個(gè)人初學(xué)開(kāi)發(fā)時(shí)都會(huì)有這種想法:要完美、要考慮周全、為了不存在的需求而編寫(xiě)一堆“預(yù)備代碼”。但是,在經(jīng)歷過(guò)幾個(gè)項(xiàng)目后總結(jié)一下,就會(huì)發(fā)現(xiàn)這種事是多么浪費(fèi)時(shí)間和精力,當(dāng)初預(yù)想的需求90%沒(méi)有出現(xiàn),出現(xiàn)的那部分也和設(shè)想大相徑庭了。
Ag:編寫(xiě)代碼時(shí),如果考慮今后的重用,工作量一般是只為當(dāng)前情況考慮的三倍。(參見(jiàn)《人月神話》)「考慮今后的重用」只能靠猜,一般都是錯(cuò)的。
讀代碼比寫(xiě)代碼難,所以那些「只為當(dāng)前情況考慮的」代碼很少在問(wèn)題稍稍發(fā)生變化的時(shí)候被改寫(xiě)成更通用的代碼。補(bǔ)充一下,原來(lái)的第三條寫(xiě)的太簡(jiǎn)短。第三條雖然再說(shuō)一個(gè)困難的現(xiàn)狀,但是它也同時(shí)說(shuō)明這是正確的重用方式。就是每次寫(xiě)代碼的時(shí)候,只為當(dāng)前情況考慮。準(zhǔn)確的說(shuō)是只為迄今為止遇到過(guò)的情況考慮。這樣一份代碼會(huì)經(jīng)歷從專(zhuān)用到通用的過(guò)程。但是這個(gè)過(guò)程也是非常困難的。
-
編程
+關(guān)注
關(guān)注
88文章
3638瀏覽量
94023 -
代碼
+關(guān)注
關(guān)注
30文章
4831瀏覽量
69112
原文標(biāo)題:是什么阻礙了代碼的重用?
文章出處:【微信號(hào):edn-china,微信公眾號(hào):EDN電子技術(shù)設(shè)計(jì)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論