內容提綱:
- 樹立正確的職業觀
- 編碼與設計
- 編程價值觀
- 什麼是好的代碼
- 代碼的壞味道
- 如何重構
1、樹立正確的職業觀
1)寫代碼這份工做,能夠幹多久?
問:是吃青春飯的玩意 答:我立刻就不編碼了,沒意思!程序員
甲:你工做多久了? 乙:六年吧! 甲:靠,六年了,你還在寫代碼啊? 乙:汗。。。。。。算法
2)寫代碼的,就是軟件藍領?
甲:最近,混得怎麼樣?據說,你還在寫代碼啊? 乙:滾,你纔在寫代碼呢,你全家都在寫代碼!數據庫
3)寫代碼的,路在何方?
- 不要被成爲項目經理,不要被成爲架構師
- 其實,咱們能夠一直在編碼!
2、編碼與設計
1)設計高於代碼?
甲(架構師):這個設計我已經所有完成了,大家編碼吧!這個星期完成! 乙們:大哥,一個星期搞不定啊! 甲:爲何? 乙們:這個設計,有點好像問題啊??按照你的設計,有不少細節,沒考慮到啊。 甲:細節?那是大家程序員的事情。我是作架構的! 乙們:無語了:cry::cry::cry:(再問就繼續被鄙視了)編程
2)最好的設計常常是在編碼階段產生的
編程前作設計這種思路是沒錯的 , 然而設計後不該該就認爲該模型就是任務的最好設計 . 你會發現最好的設計是你在編碼階段 , 一步一步逐漸造成的 。數組
3)真正的牛人是怎麼說的:
- 設計看作軟件開發的關鍵環節, 而把編程看作機械式的低級勞動 。設計就像畫工程圖紙而編碼就像施工 。可是這是錯誤的 !!!!! 軟件的可塑性更強 ,並且徹底是思想產品。
- 一些項目中,設計也許可能會詳細到可以讓編碼工做近乎機化,但不多有如此完整的設計 —— 程序員 ( 指編程 ) 一般也要部分程序進行設計,也許是正式的,也許不是。
- 有了設計 , 我能夠編程更快 , 但其中充滿小漏洞 -Alistar Cockburn
- 什麼是軟件設計? -- 代碼也是設計 © Jack W.Reeves , 1992
- 軟件系統源代碼是它的主要設計文檔 , 用來描述源代碼的圖示只是設計的附屬物而不是設計自己 . 你不該該認爲設計就是一組和代碼分離的 UML 圖 .
3、 編程價值觀
1)評價標準的背後動機-----關注開發總成本
Costtotal=Costdevelop+Costmaintainsession
----Edward Yourdon&Larry L. Constantine架構
2)軟件系統維護工做量所佔的比重超出想象!!!!!!!!
Costmaintain=Costunderstand+Costchange+Costtest+Costdeployapp
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
4、什麼是好的代碼
1)爲何要寫好的代碼
幾種想法:
- 我立刻就離職了,反正,這塊代碼我不維護了
出來混早晚是要還的,你總有一天會維護到一樣的代碼
- 原本這個就不該該是我作的,我已經很疲憊了
軟件開發界的另一個小祕密是:編寫優秀代碼和糟糕代碼所花費的時間是同樣多。一位訓練有素的工程師,他/她會從第一行代碼開始就考慮可維護性和代碼 的演化。沒有任何理由編寫「醜陋」的代碼、長達數頁的函數,或是稀奇古怪的變量名。
- 我就這水平,還不知道如何寫出好的代碼
看書、學習、多實戰
2)好代碼的重要性
- 下降維護成本
- 有助於程序員自身成長
- 有效促進團隊合做,加深小夥伴友誼
3)到底什麼是好的代碼?
不壞的代碼就是好代碼-----這不是廢話
5、代碼的壞味道
第一級
- 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(不完美的程序庫類)
6、如何重構
代碼的壞味道 | 通常重構方法 | 使用模式重構 |
---|---|---|
重複代碼 | 提煉方法 | 構造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