怎樣才能在寫代碼時沒有一種「如履薄冰」的感覺?

最近在寫C++的時候

感覺就是像題目中說的那樣 如履薄冰

個人感覺是因為各種設計混亂或者說沒有良好的設計

寫出的代碼雖然可以勉強達到目的 但是可維護性很差

經常就是添加一個功能或者模塊之後 整體都要改動

高耦合 而且以自己解耦不能(orz...) 只能求助另一些前輩

但是這樣也不能是一個常態

感覺自己這樣的狀態很不好 相當於自己搞的爛攤子請別人收拾

所以希望各位前輩指點


寫好單元測試,嗅出壞氣味,看看別人相似的項目或情況,配合版本控制,建分支嘗試各種重構,思考各種方案的優缺點。

許多方案都是對某些軟體品質的權衡,可能用性能換取可讀性,可能用額外間接減低耦合但同時增加複雜度。

經過這些之後,會更清楚問題的重心、各種解答的優缺點,自然就會更有信心。


實際工作中,

善於搞出爛攤子的人,都很快升級了;

善於重構和給別人擦屁股的人,也只能默默無聞了。

恭喜樓主加入默默無聞大軍。

----

領導、用戶、甚至同事。

他們能看到的成果,只有你搞出了多少攤子,根本看不到你做出了多少所謂優化。

你說你做了重構很爽,那只有你以為自己爽到了而已,在旁人看來,你的工作完全是原地踏步,甚至是倒退(引入新的、令他們頭疼的問題)。

另外,在一般情況下,沒有任何一個短期現實可用的數量指標可以衡量你做的重構工作會對今後很長一段時間內的開發起到什麼積極作用。評價KPI也只是短時間的事情,過了這村,就沒這店了。超長期的收益,現實中是沒辦法評價的。

雖然有時候你可以說你重構讓代碼變得清晰了,雖然你覺得客觀上對以後的開發會有很強的提升,但是以後的工作,並不一定是由你來做,所以做出來也不一定是你的成績。在領導和同事們看來,做出成績的不一定是你。他們會以為也許是那個今後負責此項目的人本來做的就挺好。

----

所以呢,在實際工作中,要善於挖坑,挖大坑,挖能讓很多人看到的坑。別去傻了吧唧的給別人填坑,你填了那麼多坑,人家看不見。

----

領導和同事,肯定希望有人可以傻傻的不斷填坑,自己挖坑,也是要相互博弈的嘛。

所以你也可以忽悠別人替你填坑,這樣就不用自己去做了。

忽悠別人幫你做填坑的事,主觀上可能大家覺得不太道德,在客觀上你高質量的完成了任務。

領導看你會來事兒,同事覺得你很重視質量,被忽悠的傢伙覺得他做的事情很重要。

從個人的角度來說,你不忽悠別人,則勢必被別人所忽悠。

從領導角度來說,他也一定會喜歡那些會挖坑的人。因為作為領導自己,一定背負著更多更嚴格的 KPI ,看著手下人不斷的做著 「優化」,卻沒有任何完成指定任務的跡象,你說他急不急?

----

現實中提倡的所謂「問題驅動」,也是如此,出了問題才去分析問題解決問題;如果不出問題,那麼事情就永遠是對的,如果你在出問題之前就已經「遇見」到問題可能會發生,則往往沒有任何說服力。用科學的方法,你得通過實驗來證明,而實際中哪有那麼充分的條件讓你做實驗?到最後還是有口難辨。只能等待若干年之後問題的出現,到時候分析和解決問題的並不是你,功勞仍然不是你的。

----

回到問題,【怎樣才能在寫代碼時沒有一種「如履薄冰」的感覺?】:

答:找現實磨練一下。


這個我可以答。設計交易策略程序時絕對是如履薄冰。因為萬一出錯的後果是真金白銀。控制模型風險可以說是策略設計最重要的一環。

首先需要有完備的單元測試。如果可以最好是獨立的個人去設計的單元測試,儘力保證每個上線的單元都沒有問題。

接下來就是題主說的問題了。這個問題是軟體工程里常見的問題。造成「牽一髮動全身」的主要原因就是系統單元間的耦合度太高。軟體工程里提到過許多解決方案,比如在設計的時候盡量抽象,降低每個單元對於輸入的假設,提高輸出數據含義的明確度等等。但實際操作中這個問題很大程度上是考驗架構師的功力,因為這有個度需要架構師去把握。要麼抽象不夠就耦合度太高牽一髮動全身,要麼抽象太高模塊含義不明確,輸入輸出定義太複雜,導致代碼極難理解和維護。

無論設計時多麼小心,總會有臨時性的代碼被加到系統里。這些代碼就好象癬疾,雖無大礙,但若置之不理它會漸漸地擴散,導致整個系統的代碼質量的降低。所以需要定期組織分析研討,哪些模塊對外部假設很高,哪些模塊輸出的含義比較模稜兩可,哪些模塊可以抽象合併,及時對它們進行清理。很多代碼分析器也可以提供相關的分析,但這個過程其實有些枯燥無聊,但要想讓系統保持長期的健康,絕對不能犯懶。

需要注意的是,無論下多大的成本,都難以保證不出錯。尤其是高速迭代的系統,出錯的可能性更大。所以監測系統運行狀態,並在出錯時及時fallback就變得很關鍵了。有些情況下監測和fallback需要的代碼量甚至超過了主程序,這樣的架構可以讓主程序迅速而安心地進行擴充而沒有太大的後顧之憂。


恭喜題主,走到了從普通開發轉向中高級開發的門檻前了,需要開始思考設計和架構。

推薦題主先搜索「S.O.L.I.D」原則。

然後買一本《設計模式》,英文原版或者中文翻譯都行。每晚抽出一小時,精讀一個模式。沒錯,用一小時細細的讀這個模式。

然後在每天的開發工作中,結合自己讀的這些東西,去思索,如何設計新模塊,如何重構老模塊。

這個過程會很痛苦。但熬過去後,就是一馬平川,整個世界都不同了。

我當初熬這個階段時,是接手一個轉了三四道手的遺留項目,見這個回答https://www.zhihu.com/question/31653614/answer/123565984

這個項目,之後又有新的一期維護+迭代,在新的這個裡,我在維護階段把整個項目逐漸重構,在迭代階段把重構後的再整個推倒重新設計。

最後,按時交貨,新的代碼里,0硬編碼 ,業務和框架全分離,支持插件擴展業務,性能持平並略有提升,完美繼承了所有功能,代碼量只有老項目的1/3。

其實新一期很坑。。。是連續來了三個項目,技術路線基本相同,業務細節不同(業務工作量大約佔一半),三個項目時間點完全重合……逼著我做業務框架分離和通用化架構。

重構過程中,除了S.O.L.I.D原則和設計模式外,C++11居功至偉(右值引用和在標準庫中的衍生功能,lambda函數,結合type_traits的模板偏特化,std::async……)。關於在生產環境如何和優雅編碼取得平衡,我和一位知友在我這個回答https://www.zhihu.com/question/19741242/answer/132455808 的評論區有討論。他認為我是何不食肉糜,我舉的例子就是這個項目——在約定的工作期限內,高質量的完成了優雅的重構。

然後我就當上了pm,現在手下2測試,4開發,項目期間九個月漲了四次薪水,順帶拿了一筆額外的獎金,現在又接手了客戶點名要我做的大項目,嗯。


我作為一個智商不夠的 API 程序員...分享一下自己的一些做法,可能不是適合所有人。

有時候經常會面對一些業務比較複雜的情況,如果沒設計好馬上動手寫代碼就會很容易出 bug。代碼裡面的細節太多了,核心的業務邏輯會淹沒在這些細節當中,debug 的時候腦子裡面沒有一個比較清晰的邏輯主線很容易暈頭轉向。所以動手之前最好先把業務邏輯理順。

我在寫代碼之前會把核心的業務邏輯抽離出來,用圖畫出來(因為腦子裡面放不下)。但是畫 UML 圖有太麻煩了又複雜,所以在大學的時候我就自己簡單地設計了一種圖來表示業務邏輯,現在我也經常用:

(iPad 畫的,原諒渣字)

不知道怎麼稱呼它,有點像時序圖和活動圖的結合..從左往右是角色,從上到下是時間。小點表示動作,三角形表示邏輯分枝,漏斗表示時間。畫起來很簡單,很快可以把這個這個業務包含了幾個角色,這些角色基於時間的動作和交互理清楚,業務邏輯的主幹一下子就出來了。(右上角是狀態機,有時候會用到)。

在畫的過程裡面把你原本寫代碼的才會想到的主要邏輯點提前進行了考慮(因為它們在整個業務上很重要的點,但是馬上寫代碼可能需要很久才會遇到)。你對整個業務有個整體的 overview,圖上有時序,不同角色之間的交互有什麼坑會提前暴露出來(例如,如果這個這個角色的這個動作在另外一個角色的時間軸上的那個點觸發會發生什麼事情)。還可以提前對可復用的邏輯進行整合(如果你發現某個部分的邏輯點是一樣的就可以把它們 join 到一起),然後整理成模塊。等等等等。

畫完以後,可以自己先過幾遍,相當於把業務邏輯提前進行演練,發現有走不通的地方可以再修改,然後就才開始寫代碼。寫代碼是充滿著細節的,這個圖放在旁邊可以保證你自己不會暈頭轉向。寫完一個模塊以後,再看看這個圖,它是屬於圖裡面的哪個一部分的,然後決定接下來應該做什麼。有什麼地方需要注意的,回顧一下,對照一下代碼有沒有考慮這些情況。寫測試的時候有很有用,畢竟圖上的重要邏輯分支可以避免不會被遺漏。

主要想表達的一個意思就是:用自己能夠理解的方式把主要業務邏輯提取出來,在寫代碼前(設計)、中(編碼)、後(測試)都圍繞著這條主線走,就不會迷路。心有成竹就不會如履薄冰。

當然,大神們可以忽略這個回答...


寫代碼之前不進行需求分析和設計建模嗎?使用用例,結構建模(類圖),行為建模(時序圖),CRC(Class-Responsibility-Collaborator)等技術進行分析和設計之後,形成需求規格說明書,和概要設計文檔並進行評審後,再進行編碼。

另外上面 @肥貓加菲 提到的代碼評審(Code Review)以及代碼風格檢查,靜態代碼分析, @Milo Yip 和 @vczh 提到的單元測試(Unit Testing)以及代碼覆蓋率度量, @stanley 提到的設計模式以及面向對象的基本原則(SOLID),應用架構模式,都是幫助提高代碼質量,可讀性,可維護性,可擴展性的方式。

關於耦合度高的問題,改一個bug動全身的問題,一方面是沒有進行充分的事前的分析和設計,另一方面是沒有掌握面向對象方法,可以找一本好一點的書來系統學習面向對象分析(OOA)和面向對象設計(OOD)和面向對象編程(OOP)方法。如何進行抽象,如何面向介面,而不是面向實現編程,如何隔離可變(或易變)的和不變的邏輯。


第一,寫單元測試,保持代碼覆蓋率(code coverage)一定程度,就可以放心代碼做了該做的功能。

第二,寫枯燥的代碼,沒錯,就是「枯燥」這個詞,不要玩花里胡哨的技巧,目標是讓一個傻子都能看懂自己的代碼,就不用擔心有人跑來問你為啥這麼寫代碼。

第三,注釋只寫為什麼,不要在注釋里寫這是做什麼什麼,說做了什麼什麼是代碼的責任,不是注釋的責任,注釋只需要解釋「為什麼」要這麼做,這樣也不會出現代碼和注釋不一致的困擾。

會上面三招,基本程序員就可以晚上睡得著,不用如履薄冰了。The

關注我吧@程墨Morgan


最近在Office組干,由於他們不用vcxproj只用cl.exe,調試略麻煩,所以我也懶得開VS了,寫代碼用notepad,沒有智能提示,感覺如履薄冰。寫完之後跑一下unittest,過了!這感覺就沒有了。

這個故事告訴我們,對於我來說,如履薄冰 == 沒有智能提示。


全面的思考

成熟的方案

充分的測試


最近在寫一個小東西,感覺在設計上也挺頭疼,還是寫的少吧,多寫多練多看就好了吧。


面向介面編程,多花點時間為類和函數想名字,盡量保證單元測試代碼能夠獨立編譯,而不是鏈接所有代碼


這是老生常談了。

可是發現好多人沒答到點子上。

個人感覺是因為各種設計混亂或者說沒有良好的設計
寫出的代碼雖然可以勉強達到目的 但是可維護性很差
經常就是添加一個功能或者模塊之後 整體都要改動
高耦合 而且以自己解耦不能(orz...) 只能求助另一些前輩

這種情況在初中級猿中很常見。1990 年代就有人如此抱怨,當時是 60、70 後,後來進入二十一世紀傳給了 80 後,現在終於輪到 90 後了。

軟體工程史上有幾個專門的術語描述這類現象:

「意麵代碼「 Spaghetti code - Wikipedia

中文形容叫「牽一髮而動全身」

「大泥球」

Big ball of mud - Wikipedia

造成「意麵代碼」或「大泥球」的直接原因,通常就是因為你貌似會寫 C++,但卻不懂 OOP 的各種設計模式與 Bad Smells(連味都聞不出,怎麼重構?)——您學的太少了。

歷來是這樣的,我國江湖上的許多碼農只學了 C++、Java 等 OOP 語言的語法規則和使用技巧,而不懂高於這些代碼、語句之上的上層抽象設計(高階的 OOP),包括 OOAD(面向對象分析與設計)中的一些關鍵設計原則(design principles)、設計模式(design patterns)等設計方法與技術。

良好的程序設計來自良好的程序設計模型(design model)。通過良好的 OOAD,往往能夠獲得穩定的設計與代碼。不懂 OOAD 與 DP,自然就不知道如何處理好大量、複雜的類與類之間、模塊與模塊之間的各種依賴、耦合關係,如何能夠適應未來可能的變化,優雅地保持代碼結構的穩定。過度耦合、不能適應變化的代碼自然是脆弱的,難以維護和修改。

但是這樣也不能是一個常態
感覺自己這樣的狀態很不好 相當於自己搞的爛攤子請別人收拾
所以希望各位前輩指點

如何從如履薄冰,到胸有成竹?

靜下心來,認真去讀懂幾本 OOAD、設計模式、UML 建模與重構的名著吧。逐漸學會在自己的大腦中用專業的 Design Model 來思考程序設計,這樣才能成長為高級猿 OOP(Object-Oriented Programmer)。


不應該用如履薄冰這個詞吧? 應該指的是 "不安全感"吧 . 反正就是"不放心", 邏輯鏈條太繁雜.

其實扯不到那些高大上的設計模式、重構亂七八糟的高大上的狗屎詞.

我說說我從學編程開始自己的習慣(沒看到什麼書說過這一點,也可以是C語言入門的緣故,或者是自己沉迷於每一行每一行扣代碼細節學會的).

只一點: 盡量極簡、流程化、自動化、順暢化.

太多人把編程當成一種控制, 一種開關控制, 或者 邏輯分支控制.

但凡你把它當成一種開關控制 或者 分岔路 引導, 編程這種活動就喪失了美.

因為整體代碼失去了流暢性、失去了流程鏈條. 而變成了一些不相關的機械開關 的 組合.

自然無從下手,自然沒邏輯可言; 自然無安全感,感覺無力控制.

然後工業作坊就衍生出了"設計模式"等等去解決這些問題, 但本質上根本問題沒解決.

我也不啰嗦了,直接說結果: 從業這麼多年來, 用到雙層嵌套循環的"機會"極少; 一個方法(函數)內一個以上的if判斷極少; if . else if .else if ,更是許久未遇; bug率低的另人髮指.

但是見周邊同事if判斷滿天飛,雙層循環到處有?

是工作經驗豐富? 是智商高?

其實都不是, 編程就是一門手藝活, 手藝活無法投機取巧, 只能一句一句代碼的扣; 這裡面沒有扯上什麼設計模式,也沒扯上啥數據結構;

因為編程每句語句之間的鏈條, 本質上就是 一種 流程化藝術, 而流程化藝術,做為程序員應該盡最大努力去保持維持 流程化 的單一性、封閉性、順暢性.

如同修築水渠, 儘可能的選擇高點, 順應水的自上而下的本能, 然後儘可能直線的挖渠, 水渠路途中儘可能少的增加分支, 不要把雜七雜八的不明不白的水源接過來; 不要破壞水的純正性, 去給"水"添亂, 入口出口盡量單一 ... 如果一定要搞狗屎分支, 儘可能的在入口或者出口去搞. 把對既定水源流程順暢的影響降到最低..僅此而已

看見沒,我強調的關鍵字是: 順應 和 不要給水添亂. 而不是控制水的走向, 你試圖去控制, 害的是你自己; 後面不知道還要增加多少狗屎代碼來一層一層的彌補修正延伸出的bug, 還有一些未知潛在的隱患.

好吧,我盡量試圖去講一些真實場景.

任何一種業務場景,必然有主樹榦流程節點, 也可以理解成占代碼量85%以上的主樹榦; 做為程序員,在開始編碼前應該仔細理解透徹"需求",並且在腦袋中逐步建立起主樹榦流程代碼; 然後拿出所有精力把這個主樹榦流程代碼銜接的細節釐清, 要確保它的順暢性; 這個理清楚了基本可以一氣呵成; 當它的順暢性完成以後, 就可以增加一些"例外判斷" 或者 "非常規流程代碼"; 這些代碼應該遵循的原則就像修水渠一樣, 不要給主樹榦添亂; 它跟你一點關係都沒有, 分支扮演的角色是輔助. (為了確保讓主樹榦邏輯流程清晰, 盡量不要多處判斷, 如果能夠在函數結尾,只做一個例外判斷處理,哪怕要多寫部分代碼,哪怕會冗餘運行一些沒必要運行的主樹榦代碼)

比如C語言中的開頭, if .... return; 這個就是流程化了, 代碼順著流程走, 在開頭例外情況 符合 就返回了; 非返回的所有代碼 代表"正常流程", 裡面沒有亂七八糟的狗屎分支.

其實改人家的代碼也是一樣道理,把它的一部分流程節點理清楚, 儘力在裡面增加極少單一分支統一處理例外情況.

說到這裡,我發現好像說著說著就要說到"代碼大全"裡面的東西了;

我也不說了, 各位架構師手下留情. (對世界上這麼多人開口閉口設計模式、重構, 真是不太理解; 編程就是一個活在當下的每一行每一行踏實碼代碼的活動, 你們要真的那麼牛逼, 到了 天天談那些設計模式啥的了,寫出的代碼就不是那麼狗屎了; )


先寫出來,然後不斷重構,直到滿意。

下次心裡就有底了。


這種情況別無他法,只有不斷重構,不斷 code review。

重構多了,自然慢慢掌握了把代碼寫性感的能力。

另外《代碼大全》等經典書籍可以看看,但最最重要的一定是動手練。


在程序員從初級向中級轉變的時候,一定會遇到類似的問題。這個時候,是程序員第二次內部拉開檔次的機會,我覺得樓主的思路非常好,將來顯然會是個很好的程序員。

我們把這個問題引申一下,分成兩個部分進行討論,第一,即樓主所述,自己的代碼勉強實現了功能,但是解耦不能。這點事實上我在之前的專欄文章有部分講述。當然理想化的方法,是在於完整設計之後,開始開發,這時候是不會出現這個問題的,然而現實情況,完整設計幾乎不會發生,原因可能來源於項目時間壓力或者人類惰性。較為普遍的情況是有一個概要設計,即進行開發。首先要明確的是,不能沒有設計,底線是你使用10%的開發工時,進行設計,根據我之前的統計,10%是底線,你必須花費足夠的時間去思考你的代碼構成。我假設你已經完成了這個部分,之後因為設計能力的限制,你必然會編寫出「如履薄冰」的代碼。這時候沒有關係。你需要採取快速原型的方法來「重構」你的方法。事實上,雖然面向對象非常多年了,我可以負責的說,我所見過的70%左右的人或者代碼,都是以面向過程的方法完成的,而面向過程的方法,其耦合度,是相當高的。在你完成了第一次代碼以後,如果你的代碼是純面向對象的,一定是很容易重構和改進的,即使你的對象設計並不完美。如果你感覺你的代碼「難看」,你可以思考一下,是否仍然是面向過程較多。

這時候,作為解耦的一個重要過程,即是抽取。

將重複代碼塊合併成一個工具方法,將重複的行為合併成一個對象方法,將重複的數據結構合併為一個對象,這就是抽取。

其次,你需要了解,邊界。

邊界是保證低耦合的關鍵,編碼的過程當中,你需要時刻注意邊界。變數有邊界,方法有邊界,對象有邊界,資料庫表有邊界,你要找到,你的功能的邊界,設置好邊界。

我們來舉個例子,仍然回到圖書管理系統這個常見的例子,很多人寫過,很多人會有「如履薄冰」的感覺。那麼,我們怎麼減少這個情況?借書,還書,入冊,很簡單,可能加一個用戶管理。

首先你要了解對象,你的動作一定由對象執行。面向過程的思路很簡單:f借書(書),這是很常見的想法,這時候不同的書可能有不同的借書條件,你就不得不寫很多if在這個方法裡面,所以你的代碼就變得難以維護,以後有變更,你就需要去改寫if或者增加if。這在面向對象裡面,是不建議的。面向對象,是對象執行方法: 書.借出().這樣就很好,我可以有一個書的基類,所有的共同方法在基類裡面,比如任何書借出,都需要記錄借書人。然而不同的書可能有不同的處理,比如貴重的書,需要這個人姓趙,那麼你就會有一個繼承了基類的書的趙書類。這樣就很好的設置了邊界,也抽取了共同的方法,之後的維護變得簡單,不會牽一髮而動全身。

所以說,總結出來,關鍵的一點就是嚴格按照面向對象的方法來設計你的程序,就可以大大減少這種「如履薄冰」感。當然,面向對象的設計技巧又有很多,這個我們可以另外討論。

其實,第二部分,樓主將來可能遇到,才是更麻煩的,即基於老代碼的二次開發。這更容易給人帶來「如履薄冰」,老代碼一沒人懂,二寫的差,在更改老代碼的時候,非常容易出現高耦合解不開,只能完全繞開,打一個patch了事,導致代碼維護性原來越差。有得人可能會提出,我完全拋棄,重新寫一個。這種在百萬行代碼的級別,somehow還能實現,帶千萬行以上,你敢,老闆也不敢。這是常見的情況。這個情況下,的確是很難處理的,我根據我多年處理類似代碼的狀況,提出一個概念,叫做特修斯式重構。目前來說,重構基本上需要產品下線,暫停開發,這個很多時候是很奢侈的,你只能在線做,但是不做不行。我的建議是,首先設計一個你想要的框架,比如我常用spring的組合,其次,你的框架會和現行框架並行運作,採取侵入式的方式,在每個層之間獲取控制權,這即是設置邊界,在你獲取到了邊界的控制權之後,(這可能是漸進的,你的系統可能有100個方法,你可以一個方法一個方法地獲取控制權),你要做的是對外保證behavior仍然正確,這時候你就架空了這個方法,你可以開始重構這個方法,以此類推,知道整個系統被你換掉,那一天,底層框架也被你完全架空了,你就可以扔掉它了。這一點上,雖然我有些ppt,不過基本上都是公司機密,就不貼圖了。


"寫出的代碼雖然可以勉強達到目的 但是可維護性很差
經常就是添加一個功能或者模塊之後 整體都要改動
高耦合 而且以自己解耦不能(orz...) 只能求助另一些前輩"

首先,你確信你理解需求了嗎?

要做到好的可重用性,你需要深刻理解需求。不僅是你所負責模塊,還要了解你負責模塊所在的環境甚至是整個系統級別的需求。要做到好的可重用,最基本的要求就是隔離易變和不易變的部分,而判斷哪些易變哪些不易變需要你對需求有深刻的認識。

其次,你的理論知識和實踐經驗夠嗎?

你知道開閉原則,里氏替換,依賴注入,各種設計模式的原理和使用場景嗎?你能熟練的使用自上而下的思考方式嗎? 你有從大量的重構中悟出哪些是潛在的不合理設計嗎?

是的,這對初學者確實有點難。但每個在軟體設計方面信心滿滿的程序員都需要經過這樣的歷練。

加油吧,騷年。


那是因為你寫的太少,不知道怎麼樣設計最科學。等你寫個幾年一切都煙消雲散。

快速長進辦法就是請別人給你code review一下。還有就是要有一本規範,有規範看代碼不累。最後就是重構然後總結。但是現在不建議你每天改啊改的,因為你現在不會評估重構的合理性,改也白改。我最開始的時候也老喜歡改別人代碼。其實只有值得改的才需要改,不值得改的部分不如寫兩句注釋。


我的經驗是在設計階段考慮得越全面,越細緻,寫起代碼來更順暢,質量也越高,就像翻譯一樣,那種感覺真的很爽!

之前就有壞習慣就是一想到解決方法了就很興奮的寫代碼。結果往往寫出來的代碼很臟。


為什麼寫代碼時會覺得如履薄冰?

  1. 因為很多時候我們太急著寫代碼,而理解問題的時間不夠,如果把多一點時間花在理解問題上,不立刻用代碼鋪陳實現,而只寫一點篇幅小的驗證代碼,讓自己有一個平緩的坡度,從陌生到熟悉,到最後徹底地理解問題,這種感覺就不會這麼明顯
  2. 因為有時候我們編程的過程不夠有機,而因為迷信某些技巧或者實踐,讓我們的思維變得過於生硬;生搬硬套某些東西,而對這些東西的理解不夠充分,只是用個樣子,有些時候本來就不合適,卻想著要把它們湊合到一起;而有機的迭代過程,是從對問題的理解觸發,盡量保持設計的簡單,剋制引入複雜結構的衝動,除非絕對必要,讓一個設計慢慢的長大,自己的理解也慢慢加深,真實的需求會逐漸呈現出來,如果這樣設計程序,就不太會覺得如履薄冰,因為每一個步驟我們心裡知道都不十分完美,但心裡都有數;所以如果你能從簡單的函數開始,就控制住設計複雜類系的衝動,也許慢慢會需要用到類,但可以在中途實現,不需要一上來就太多設計負擔
  3. 因為我們太急,過於看重結果,而忽視開發的規律。實際開發,每一個領域從問題需求到形成比較穩定優美的代碼實現,至少都需要幾周時間,這並不誇張,很多時候,一個局部的代碼,看上去只有幾個文件,但真正迭代起來,到你覺得比較好的程度,用幾個月的時間是很正常的。因為很少有開發的問題從一開始你就知道所有細節,都是做著做著逐漸暴露出來的,如果開發人員沒有耐心和平常心,違背複雜設計的規律,太急,就會有如履薄冰的感覺,因為總感覺結果不滿意,但其實這是完全正常的設計階段
  4. 也只是因為我們還缺乏經驗,同一類問題,比如設計一套緩存系統,第一次做很難覺得放心,但做過一兩次,經過一段時間的檢驗以後,以後就可以快速而比較自信的復用之前的設計了,這就是經驗,有了經驗就可以成竹在胸,該碰到的問題都碰到過了,該做的改進也都做過了,對於問題領域的已知已經大大超過未知,就不會覺得「如履薄冰「了,所以你只需要保持對技術的學習投入,積累寶貴經驗。


推薦閱讀:

用 C++ 編程時,如果不使用設計模式,多層封裝,採用複雜的數據結構,代碼更直觀,易理解,引入(設計模式)後雖然做到了高度的解耦。但是代碼邏輯複雜了,怎麼平衡好?
有哪些在實際 Android 項目中用到的設計模式?
Android 開發中常用到的設計模式有哪些?
最上層的語言和最底層的語言都無需設計模式?
使用IoDH的單例寫法,靜態內部類的instance變數是否一定需要聲明為final?

TAG:編程 | 計算機 | C | 代碼質量 | 設計模式 |