序
《代碼大全》堪稱編程界的經(jīng)典辐烂,之前一直被同行推薦遏插,直到最近才得以閱讀實(shí)踐,目前簡單讀了一些章節(jié)纠修,也有在做讀書筆記胳嘲,所以在這也想簡單分享給大家。
這本書已經(jīng)經(jīng)歷了快一個世紀(jì)分瘾,卻經(jīng)久不衰胎围,被翻譯成了多種語言吁系,至今很多設(shè)計(jì)理念來悄悄地影響我們的程序設(shè)計(jì)德召。原本我只是一個喜歡讀應(yīng)用類書籍的人,最近被這本書著實(shí)開啟了新板塊的大門汽纤。
此書的每一頁都是真知灼見上岗,每一行文字都來自數(shù)年的編程實(shí)踐總結(jié),必須是軟件設(shè)計(jì)成功的理念引導(dǎo)蕴坪。
套用某位程序員的話:
開始編程的時候肴掷,讀的不知所云;
敲了一年代碼之后背传,讀的如飲甘泉呆瞻,醍醐灌頂,如獲獨(dú)孤九劍一般径玖;
敲了五年代碼之后痴脾,讀的吹毛求疵,雞蛋里面挑骨頭說梳星,這里過時了赞赖,這里不合理......
現(xiàn)在敲了十年代碼了滚朵,再次去翻,不覺嘆息前域,方知經(jīng)典永不褪色辕近。
下面是目前的讀書筆記。
第 1 章:歡迎進(jìn)入軟件構(gòu)建的世界
第 2 章:用隱喻來更充分地理解軟件開發(fā)
第 3 章:三思而后行:前期準(zhǔn)備
第 4 章:關(guān)鍵的 “構(gòu)建” 決策
第 5 章:軟件構(gòu)建中的設(shè)計(jì)
5.1 設(shè)計(jì)中的挑戰(zhàn)
- 設(shè)計(jì)是一個險惡的問題匿垄;
- 設(shè)計(jì)是個了無章法的過程 => 直到你沒時間做了為止移宅。
- 設(shè)計(jì)就是確定取舍和調(diào)整順序的過程。
- 設(shè)計(jì)受諸多限制椿疗。
- 設(shè)計(jì)是不確定的吞杭。
- 設(shè)計(jì)是一個啟發(fā)式過程。
- 設(shè)計(jì)是自然而然形成的变丧。
幾乎所有的系統(tǒng)都在其開發(fā)的起始階段經(jīng)歷某種程度的設(shè)計(jì)變更芽狗,而當(dāng)它們進(jìn)入到后續(xù)版本中都會進(jìn)行更大的改變。軟件的性質(zhì)決定了這些改變在多大程度上是有益且可被接受的痒蓬。
5.2 關(guān)鍵的設(shè)計(jì)概念
軟件的首要技術(shù)使命:管理復(fù)雜度童擎。
- 將整個系統(tǒng)拆解為多個子系統(tǒng);
- 保持子程序的短小精悍:從問題的領(lǐng)域著手攻晒,而不是從底層實(shí)現(xiàn)細(xì)節(jié)入手去編寫程序顾复。
- 寫出容易讓人理解的代碼;
如何應(yīng)對復(fù)雜度
高代價鲁捏、低效率的設(shè)計(jì)一般來源于: - 用復(fù)雜的方法解決簡單的問題芯砸;
- 用簡單但錯誤的方法解決復(fù)雜的問題;
- 用不恰當(dāng)?shù)膹?fù)雜方法解決復(fù)雜的問題给梅;
解決方法: - 把任何人在同一時間需要處理的本質(zhì)復(fù)雜度的量降到最屑偕ァ;
- 不要讓偶然性的復(fù)雜度無畏地快速增長动羽;
理想的設(shè)計(jì)特征 - 最小的復(fù)雜度包帚;
- 易于維護(hù);
- 松散耦合运吓;
- 可拓展性渴邦;
- 可重用性;
- 高扇入:讓大量的類使用某個特定的類拘哨。
- 低扇出:一個類里少量或適中地使用其他類谋梭。
- 可移植性。
- 精簡性倦青。
- 層次性瓮床。
第 6 章:可以工作的類
6.1 類的基礎(chǔ):抽象數(shù)據(jù)類型 ADTs
定義:指一些數(shù)據(jù)以及對這些數(shù)據(jù)所進(jìn)行的操作的集合。
使用 ADT 的益處:
- 可以隱藏實(shí)現(xiàn)細(xì)節(jié);
- 改動不會影響到整個程序纤垂;
- 讓接口提供更多信息矾策;
- 更容易提高性能;
- 讓程序的正確性顯而易見峭沦;
- 程序更具自我說明性贾虽;
- 無須在程序內(nèi)到處傳遞數(shù)據(jù);
- 你可以像在現(xiàn)實(shí)世界中那樣操作實(shí)體吼鱼,而不用在底層實(shí)現(xiàn)上操作它蓬豁;
6.2 良好的類接口
6.2.1 良好的封裝:
- 盡可能地限制類和成員的可訪問性;
- 不要公開暴露成員數(shù)據(jù)菇肃;
- 避免把私用的實(shí)現(xiàn)細(xì)節(jié)放在類的接口中地粪;
- 不要對類的使用者做出任何假設(shè);
- 避免使用友元類琐谤;(友元類是 C++ 中的概念蟆技,可以訪問其他類的私有成員)
- 不要因?yàn)橐粋€子程序里僅使用公共子程序,就把它歸為公開接口斗忌;
- 讓閱讀代碼比編寫代碼更方便质礼;
- 要格外警惕從語義上破壞封裝性;
- 留意過于緊密的耦合關(guān)系织阳;
6.3 有關(guān)設(shè)計(jì)和實(shí)現(xiàn)的問題
- 警惕超過約 7 個數(shù)據(jù)成員的類眶蕉;
- 讓類中子程序的數(shù)量盡可能的少;
- 禁止隱式地產(chǎn)生你不需要的成員函數(shù)和運(yùn)算符唧躲;
- 減少類中所調(diào)用的不同子程序的數(shù)量造挽;
- 對其他類的子程序的間接調(diào)用盡可能的少;
- 一般來說弄痹,應(yīng)盡可能減少類和類之間相互合作的范圍饭入,盡量讓下面這幾個數(shù)字最小:
- 所實(shí)例化的對象的種類界酒;
- 在被實(shí)例化對象上直接調(diào)用的不同子程序的數(shù)量圣拄;
- 調(diào)用由其他對象返回的對象的子程序的數(shù)量嘴秸;
6.4 創(chuàng)建類的原因
- 為現(xiàn)實(shí)世界中的對象建模毁欣;
- 為抽象的對象建模;
- 降低復(fù)雜度岳掐;
- 隔離復(fù)雜度凭疮;
- 隱藏實(shí)現(xiàn)細(xì)節(jié);
- 限制變動的影響范圍串述;
- 隱藏全局?jǐn)?shù)據(jù)执解,盡可能通過方法來對數(shù)據(jù)進(jìn)行訪問或修改;
- 讓參數(shù)傳遞更順暢;
- 建立中心控制點(diǎn)衰腌;
- 讓代碼更易于重用次坡;
- 為程序族做計(jì)劃:把某些預(yù)料到可能會改的抽離到單獨(dú)的類中忧陪;
- 把相關(guān)操作包裝在一起;
- 實(shí)現(xiàn)某種特定的重構(gòu);
- 避免創(chuàng)建萬能類壶唤;
- 消除無關(guān)緊要的類;
- 避免用動詞命名的類:只有行為而沒有數(shù)據(jù)的類往往不是一個真正的類军援;
第 7 章:高質(zhì)量的子程序
7.1 為什么要創(chuàng)建子程序宠进?
- 降低復(fù)雜度,讓每段代碼都具有單一職責(zé)萝风;
- 引入中間嘀掸、易懂的抽象;
- 避免代碼重復(fù)规惰;
- 支持子類化睬塌;
- 隱藏順序;
- 隱藏指針操作歇万;
- 提高可移植性衫仑;
- 簡化復(fù)雜的布爾判斷:把一切復(fù)雜的判斷放入單獨(dú)的函數(shù)中;
- 改善性能:性能一次優(yōu)化堕花,能遍布到所有調(diào)用點(diǎn)文狱;
- 確保所有的子程序最小缘挽;
7.2 在子程序上設(shè)計(jì)
內(nèi)聚性主要是讓每一個子程序去做最單一的事情瞄崇,比如單位換算,我們可能很多地方會使用壕曼,把其計(jì)算方式抽離出來苏研,這就是一個實(shí)現(xiàn)內(nèi)聚性的展現(xiàn)。
7.3 要起一個好的子程序名字
- 描述子程序所做的所有事情腮郊;
- 避免使用無意義摹蘑、模糊或表述不清的動詞;
- 不要僅通過數(shù)字來形成不同的子程序名字:比如 part1,part2;
- 根據(jù)需要確定子程序名字長度:通過最佳為 9 - 15 個字符轧飞;
- 給函數(shù)命名時要對返回值有所描述衅鹿;
- 給過程起名時使用語氣強(qiáng)烈的動詞加賓語的形式,比如 printDocument()过咬,checkOrderInfo() 等大渤,在面向?qū)ο蟮恼Z言中,最好通過多態(tài)而不用加對象:比如 document.print()掸绞,orderInfo.check()泵三;
-
準(zhǔn)確適用對仗詞:列舉常用對仗詞組:
- 為常用操作確定命名規(guī)則;
7.4 子程序可以寫多長?
理論上烫幕,一般子程序保持在 50-150 行為宜俺抽。
7.5 如何使用子程序參數(shù)
- 不要把子程序的參數(shù)作為工作變量:即在子程序最好不要去修改輸入?yún)?shù)的值;
- 把子程序的參數(shù)限定在 7 個以內(nèi)较曼;