如何寫好代碼


內容提綱:

  • 樹立正確的職業觀
  • 編碼與設計
  • 編程價值觀
  • 什么是好的代碼
  • 代碼的壞味道
  • 如何重構

一、樹立正確的職業觀

1)寫代碼這份工作,可以干多久?

問:是吃青春飯的玩意 答:我馬上就不編碼了,沒意思!

甲:你工作多久了? 乙:六年吧! 甲:靠,六年了,你還在寫代碼啊? 乙:汗。。。。。。

2)寫代碼的,就是軟件藍領?

甲:最近,混得怎么樣?聽說,你還在寫代碼啊? 乙:滾,你才在寫代碼呢,你全家都在寫代碼!

3)寫代碼的,路在何方?

  • 不要成為項目經理,不要成為架構師
  • 其實,我們可以一直在編碼!

二、編碼與設計

1)設計高於代碼?

甲(架構師):這個設計我已經全部完成了,你們編碼吧!這個星期完成! 乙們:大哥,一個星期搞不定啊! 甲:為什么? 乙們:這個設計,有點好像問題啊??按照你的設計,有很多細節,沒考慮到啊。 甲:細節?那是你們程序員的事情。我是做架構的! 乙們:無語了:cry::cry::cry:(再問就繼續被鄙視了)

2)最好的設計經常是在編碼階段產生的

編程前做設計這種思路是沒錯的 , 然而設計后不應該就認為該模型就是任務的最好設計 . 你會發現最好的設計是你在編碼階段 , 一步一步逐漸形成的 。

3)真正的牛人是怎么說的:

  • 設計看做軟件開發的關鍵環節, 而把編程看做機械式的低級勞動 。設計就像畫工程圖紙而編碼就像施工 。但是這是錯誤的 !!!!! 軟件的可塑性更強 ,而且完全是思想產品。
  • 一些項目中,設計也許可能會詳細到能夠讓編碼工作近乎機化,但很少有如此完整的設計 —— 程序員 ( 指編程 ) 通常也要部分程序進行設計,也許是正式的,也許不是。
  • 有了設計 , 我可以編程更快 , 但其中充滿小漏洞 -Alistar Cockburn
  • 什么是軟件設計? -- 代碼也是設計 © Jack W.Reeves , 1992
  • 軟件系統源代碼是它的主要設計文檔 , 用來描述源代碼的圖示只是設計的附屬物而不是設計本身 . 你不應該認為設計就是一組和代碼分離的 UML 圖 .

三、 編程價值觀

1)評價標准的背后動機-----關注開發總成本

Costtotal=Costdevelop+Costmaintain

----Edward Yourdon&Larry L. Constantine

2)軟件系統維護工作量所占的比重超出想象!!!!!!!!

Costmaintain=Costunderstand+Costchange+Costtest+Costdeploy

Costmaintain>>Costdevelop

3)代碼要人能夠讀懂------Martion Fowler

任何一個傻瓜都能寫出機器能懂的代碼,好的程序員應該寫出人 能懂的代碼。

----Martin Fowler 《重構》

4)程序員要有這種意識------"寫爛代碼要遭報應!!!!!!!!!"

編程的時候,總是想着那個維護你代碼的人會是一個知道你住在 哪兒的有暴力傾向的精神病患者。

----Martin Golding

5)軟件代碼3項職責------Robert C Martin <敏捷軟件開發>

  • 第1職責:運行起來所完成的功能,這是模塊存在的原因。
  • 第2職責:要和閱讀它的人進行溝通,對模塊不熟悉的人員應該能夠比較容易理解。
  • 第3職責:它要應對變化,因為軟件要變化,開發者保證應該盡可能的簡單。

6)價值觀是編程過程的統一支配性主題.有3個價值觀:

  • 溝通:珍視與他人溝通的重要性
  • 簡單:把多余的的復雜性去掉
  • 靈活:保持開放,應對變化

——Kent Beck

7)整潔代碼------百家爭鳴

隨着年齡的增長,我逐漸意識到編程不僅僅是讓程序運行而已; 編程是創造一個易於理解的、可以維護的、高效的作品。一般來 說,干凈整潔的代碼,往往運行起來更快。這與流行觀點正好相 反。而且即使它們不快,也可以很容易地讓它們變快。正如人們 所說的,優化正確的代碼比改正優化過的代碼容易多了。

---- Google公司首席Java架構師Joshua Bloch

我喜歡優雅和高效的代碼。代碼邏輯應當直截了當,叫缺陷難 以隱藏;盡量減少依賴關系,使之便於維護;依據某種分層戰 略完善錯誤處理代碼;性能調至最優,省得引誘別人做沒規矩 的優化,搞出一堆混亂來。整潔的代碼只做好一件事。

----Bjarne Stroustrup, inventor of C++ and author of The C++

整潔的代碼簡單直接。整潔的代碼如同優美的散文。整潔的代 碼從不隱藏設計者的意圖,充滿了干凈利落的抽象和直截了當 的控制語句

----Grady Booch,Object Oriented Analysis and Design with Applications

p整潔的代碼應可由作者之外的開發者閱讀和增補。它應當有單 元測試和驗收測試。它使用有意義的命名。它只提供一種而非 多種做一件事的途徑。它只有盡量少的依賴關系,而且要明確 地定義和提供清晰、盡量少的API。代碼應通過其字面表達含 義,因為不同的語言導致並非所有必需信息均可通過代碼自身 清晰表達

----“老大”Dave Thomas,OTI公司創始人,Eclipse戰略教父

我可以列出我留意到的整潔代碼的所有特點,但其中有一條是根 本性的。整潔的代碼總是看起來像是某位特別在意它的人寫的。 幾乎沒有改進的余地。代碼作者什么都想到了,如果你企圖改進 它,總會回到原點,贊嘆某人留給你的代碼—全心投入的某人留 下的代碼。

----Michael Feathers,Working Effectively with Legacy Code

四、什么是好的代碼

1)為什么要寫好的代碼

幾種想法:
  • 我馬上就離職了,反正,這塊代碼我不維護了

出來混遲早是要還的,你總有一天會維護到同樣的代碼

  • 本來這個就不應該是我做的,我已經很疲憊了

軟件開發界的另外一個小秘密是:編寫優秀代碼和糟糕代碼所花費的時間是一樣多。一位訓練有素的工程師,他/她會從第一行代碼開始就考慮可維護性和代碼 的演化。沒有任何理由編寫“丑陋”的代碼、長達數頁的函數,或是稀奇古怪的變量名。

  • 我就這水平,還不知道如何寫出好的代碼

看書、學習、多實戰

2)好代碼的重要性

  • 降低維護成本
  • 有助於程序員自身成長
  • 有效促進團隊合作,加深小伙伴友誼

3)到底什么是好的代碼?

  不壞的代碼就是好代碼-----這不是廢話

五、代碼的壞味道

第一級
  • Duplicated Code(重復代碼)
  • Long Method(過長函數)
  • Large Class(過大類)
  • Long Parameter List(過長參數)
  • Comments(過多的注釋)
  • Temporary Field(令人迷惑的暫時值域)
  • Primitive Obsession(基本型別偏執狂)
  • Switch Statements(Switch驚悚現身)
  • Divergent Change(發散式變化)
  • Shotgun Surgery(散彈式修改
第二級
  • Data Clumps(數據泥團)
  • Data Class(幼稚的數據類)
  • Feature Envy(依戀情結)
  • Refused Bequest(被拒絕的遺贈)
  • Message Chains(過度耦合的消息鏈)
  • Middle Man(中間轉手人)
  • Inappropriate Intimacy(狎昵關系)
  • Lazy Class(冗余類)
第三級
  • Parallel Inheritance Hierarchies(平行繼承)
  • Speculative Generality(理論上的一般性)
  • Alternative Classes with Different Interfaces(異曲同工類)
  • Incomplete Library Class(不完美的程序庫類)

六、如何重構

代碼的壞味道 一般重構方法 使用模式重構
重復代碼 提煉方法 構造Template Method
以Composite取代一/多之分
引入Null Object
用Adapter統一接口
用Fatory Method引入多態創建
提取類
方法上移
替換算法
鏈構造方法
過長方法 提取方法 轉移聚集操作到Vistor
以Strategy取代條件邏輯
以Command取代條件調度程序
轉移聚集操作到Collecting Parameter
組合方法
以查詢取代臨時變量
引入參數對象
保持對象完整
過長參數列 以方法取代參數  
引入參數對象
保持對象完整
條件邏輯過度復雜 分解條件式 以Strategy取代條件邏輯
轉移裝飾功能到Decorator
以State取代狀態改變條件語句
引入Null Object
合並條件式
合並重復的條件片段
移除控制標記
以衛語句取代嵌套條件式
以多態取代條件式
引入斷言
分支語句 提取方法 以State/Strategy取代類型代碼
引入Null Object
以Command替換條件調度程序
轉移聚集操作到Visitor
轉移方法
以子類取代類型代碼
以多態取代條件式
已明確方法取代參數
基本類型迷戀
程序代碼過於依賴基本類型(int,string,double,array等低層次語言要素)
以對象取代數據值 以State取代狀態改變條件語句
以Strategy取代條件邏輯
以Composite取代隱含樹
以Interpreter取代隱式語言
轉移裝飾功能到Decorator
用Builder封裝Composite
以類型取代類型代碼
以子類取代類型代碼
提取類
引入參數對象
以對象取代數組
數據泥團
在類的字段和參數列中,總是一起出現的數據
提取類  
引入參數對象
保持對象完整
令人迷惑的臨時字段 提取類 引入Null Object
組合爆炸
許多段代碼使用不同種類或數量的數據
或對象做同樣的事情(例如使用特定條件和數據庫查詢)
  以Interpreter取代隱式語言
過大類 提取類 以Command取代條件調度程序
以State取代狀態改變條件語句
以Interpreter取代隱式語言
提取子類
提取接口
復制被監視數據
冗贅類
不再做很多工作或沒有用的類
折疊繼承關系  
內聯Singleton
不恰當的暴露
在客戶代碼中不應看到類的字段和方法,卻是公開可見的
封裝字段 用Factory封裝類
封裝群集
移除設置方法
隱藏方法
發散式變化
類經常因為不同的原因在不同方向上發生變化,顯然是違反了單一職責原則
提取類  
霰彈式修改
如果遇到變化,必須在不同的類中作出相應的修改
轉移方法 將創建知識搬移到Factory
轉移字段
內聯類
依戀情結
方法對於某個類的興趣高過對自己所處的宿主類
轉移方法 引入Strategy
引入Visitor
提取方法
平行繼承體系
當為一個類增加一個子類時,也必須在另一個類中增加一個相應的子類
轉移方法  
轉移字段
誇誇其談未來性 折疊繼承關系  
內聯類
移除參數
移除方法
過度耦合的消息連
不斷的向一個對象索求另一個對象
隱藏委托 使用抽象引入Chain Of Responsibility
提取方法
轉移方法
中間轉手人
類之間彼此依賴於其private成員
移除中間轉手人  
內聯方法
以繼承取代委托
狎昵關系
類之間彼此依賴於其private成員
轉移方法  
將雙向關聯改為單向
提取類
隱藏委托
以繼承取代委托
異曲同工的類 重命名方法 用Adapter統一接口
轉移方法
提取超類
不完善的程序庫類 引入外加方法 用Adapter統一接口
用Facade封裝類
引入本地擴展
純稚的數據類
只擁有字段的數據類
封裝字段  
封裝集合
移除設置方法
轉移方法
隱藏方法
被拒絕的遺贈
繼承父類時,子類想要選擇繼承的成員
以委托取代繼承  
過多的注釋
為糟糕的代碼寫大量的注釋
使用一起重構方法,使方法本身達到自說明的效果,讓注釋顯得多余  
怪異解決方案
在同一系統中使用不同的方式解決同一問題
替換算法 用Adapter統一接口

介紹幾本好書:

  • 《代碼整潔之道》----Robert C. Martin
  • 《敏捷軟件開發:原則、模式與實踐》----Robert C. Martin
  • 《代碼大全》 ----Steve McConnell
  • 《重構——改善既有代碼的設計》 ----Martin Fowler

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM