日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何编写好的代码?

發布時間:2024/4/11 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何编写好的代码? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

hi,各位小伙伴,大家好,最近主導項目正在進行code review,發現不同人寫代碼風格不一樣:

  • 完成任務型,怎么簡單怎么來,目的快速完成任務,盡量復制粘貼搞定,沒有自己的代碼設計思想,代碼雜亂無章,不喜歡重構,bug多。

  • 實用性,注重簡潔,能不新增代碼,就盡量不新增代碼,設計比較簡單,擴展性一般,但可以滿足需求,不到萬不得已不會重構代碼,對系統侵入性小,bug少。

  • 過度設計型,注重解耦(添加中間層),可以稱為解耦大師,代碼層次豐富,可擴展強,喜歡重構老代碼,一般人不易看懂,需要花大量時間理解其設計,對系統侵入性大,bug多(因為新增代碼多,bug也會增多,需要各種測試手段才能讓其穩定下來)。

你是哪種類型呢,還是混合型(不同情況,不同比例)?

讓我們看一看如何編寫好的代碼。

Programs are meant to be read by humans and only incidentally for computers to execute. ——Donald Knuth
“代碼始終是寫給人看的,只是恰好能被計算機執行。”

什么是好的代碼?局部干凈,核心邏輯簡潔。

本文是一篇總結筆記,是以往工作學習中關于如何實現“局部干凈”的一些見聞、教訓、團隊實踐和一些思考。寫出整潔代碼不僅需在函數、類級別上用功,也應該理解一些其他主題,如項目架構、設計原則等,軟件工程是復雜(complex)的,只有各個方面都處理得干干凈凈,才能在整體上做到代碼整潔。

指導原則:消除重復,分離關注點,統一抽象層次

程序員終其一生所做得事大抵不超過這幾個層次

  • 函數與類

  • 包與模塊(依賴)

  • 服務(系統)與服務域

  • 產品

在各個層面,這十五個字都足以作一些指導或參考。

消除重復

重復的代碼會讓系統臃腫,難以維護,增加程序員的心智負擔。消除重復的手段不外乎封裝,抽取函數、類等。

  • 代碼重復

  • 完完全全重復的代碼,應該抽取出公共的函數。同一段代碼出現兩次及以上,就應該抽取出函數。

  • 結構重復

  • 代碼雖然不一樣,但結構類似,也應該抽取。結構重復可以推導出一些高級技術,如

    • 繼承體系

    • 泛型

    • 模板方法(template method,四人幫 23 種設計模式之一)

    • 高階函數,lambda

    可惜的是,這些在 golang 里支持不夠,各有喜憂。

  • 過程重復

  • 如果總是重復做同一件事,應該使其自動化。

    分離關注點

    物以類聚,人以群分,代碼也是一樣。關注點相同的代碼應該在一起,天然具有親和性,這句話的另一個含義,對關注點不同的代碼天然具有隔離性,相互之間不應該太深入了解。

  • 分離主線和支線

  • 這是最應該注意的,特別是在業務代碼開發中。主要業務邏輯是主線,應該突出主線,淡化支線,按照人的思維,這樣才是好理解的。例如旋律音和伴奏音,應該突出旋律,而淡化伴奏。假使伴奏音和旋律音差不多強,喧賓奪主,這樣的音樂一定是難聽的,因為我們聽不出旋律。代碼也是這樣,應該突出主線,使核心邏輯一目了然。

    例如在下單的邏輯中,可能的主線是:檢查庫存、檢查余額、生成訂單。那這個下單方法里就應該只有 3 行代碼,而不應該有諸如權限判斷、性能記錄等,如果出現就會有 2 行代碼是跟主線無關的,造成不必要的干擾,不要造成無謂的心智負擔,應該解放心智去完成更復雜的事情。

    分離主線和支線的技術如:

    • AOP

    • interceptor、filter 等

  • 分離技術和業務

  • 技術型代碼常常是公用的,如日期計算、日志記錄、性能測量、數據庫鏈接、基礎工具類。這些應該和業務邏輯分開,相信這點大家都沒有疑問。

  • 按業務性質分離

  • 對業務開發來說,業務知識永遠都是第一位的。一個技術水平很高的程序員,但是對業務不理解,他也發揮不了全部水平,就像殺雞用牛刀,施展不了全部功力。不同業務應該分開,在模塊級、服務級甚至更高的產品級,這也應該是共識。但是在一個系統內部,推薦也應該按業務分成不同的包,同一業務下的對象是天然親和的,同樣也是對不同業務的對象是隔離的。

  • 分離變化快慢的代碼

  • 變化快的代碼和長年不變的代碼分開。

  • 分離性能高低的代碼

  • 重 I/O 的代碼和重 CPU 的代碼理應分開,方便合理分配資源,其他諸如此類的代碼應該注意分開。

    統一抽象層次

    將有關認識與那些在實際中和他們同在的所有其他認識隔離開,這就是抽象,所有具有普遍性的認識都是這樣得到的。——John Locke 《關于人類理解的隨筆》

    怎么理解抽象?抽象的反面是具體,具體是細節,可見抽象是細節的反面,抽象刻畫了統一的畫像,描述能力,是對事物在某些方面的特征的提取總結。總之,抽象表達的是意圖,另一個理解就是,它不表達細節。“Tom 要成為世界首富”,這句話的抽象層次就很高,意圖很明顯,但是關于 Tom 如何成為世界首富、用什么貨幣衡量等細節,一概不知。抽象層次高,偏意圖,語義(代碼在上下文中表達的語義)清晰,信息量小;抽象層次低,偏實現,語義模糊,信息量大。

    兩個原則:

    • 同一抽象層次上的對象才能直接對話;

    • 同一抽象層次上的對象之間存在著緊密合作;

    典型的函數結構

    一個好的函數結構,應該這樣像一棵樹一樣層次分明。一方面,每一個層次都只有 2~5 個步驟,一般而言我們做一件事也就 2~5 個步驟,分解太多太少都不好,太少沒必要分解,太多記不住,增加心智負擔。實際上,更多的情況,我們都喜歡 3 這個數字,例如在會議總結時,總結 3 點足夠了,更多估計不會有太多人愿意繼續集中注意力聽超過 3 點的總結。所以一個好的函數,不應該超過 5 行,我們之所以做不到,除了抽象層次劃分不準確之外,還有很大一部分原因是表達能力不足,畢竟英語不是我們的母語。(函數 10 行代碼,是我在過去工作中合代碼的及格線,20 行是紅線。)另一方面,只有葉子節點才表達實現,非葉節點都應該表達意圖。

    以“把大象裝進冰箱”為例,不外乎三步:

  • 打開冰箱門

  • 放進大象

  • 關閉冰箱門

  • 所以關于如何把大象切成碎片,不應該出現在上面,應該在步驟 2 的后續調用中。

    由這個函數結構還可以得見,好的程序讀起來應該像自然語言,極少部分像數學語言(偏算法),不好的程序讀起來就像是程序。當我們讀一段程序,一眼看去它就像是程序,那不是它太好,它就是不夠好的。一直認為,寫作能力才是成為優秀程序員最重要的能力。

    隔離與隱藏

    信息隱藏,是抽象的一種手段。通過信息隱藏,來暴露只想讓外界知道的東西,表達意圖。隔離是實現信息隱藏的重要手段。隱藏與隔離有一個天然的好處,例如我們有一個包,我們只提供數個 public 的方法,包內的其他對象、方法都只是包可見的,這樣,我們可以隨意修改內部實現,只要保證那些 public 方法的行為不變。特別是對于復雜系統,如果做不好隔離與隱藏,到處都是 public 方法,到后面誰都不敢隨意改動代碼,誰也不知道哪位大哥在方法上加了一個 if-else 分支。

    編碼 tips

    以下都是一些簡單實用的技術,以如何寫出整潔代碼,很多是出自《代碼整潔之道》,一些是出自過去團隊的經驗。

    1. 類

  • 類應該足夠小

  • 最初級的程序員可能會在一個 Controller 里做完所有的業務邏輯,最終會使這個類成為 God Class。一個類太大,代碼太多,會使類的結構不清晰,職責混亂,維護代碼時花費很多時間去尋找修改位置。譬如我們所見的世界,由分子、原子甚至更小的粒子排列組合而成,所以才有繽紛多彩的各色物質(對象),但如果構成物質的最小粒子就是人,那還能組合出什么其他物質呢?代碼也是如此,類應該足夠小,才能發揮排列組合的威力。

  • 單一職責

  • 類的職責應該單一,即“SOLID”五大原則的 S,職責單一意味著,“只有一個理由可以修改它”。另外,類名一般而言應該是名詞,且描述其職責。

    如果無法為一個類名以精確的名稱,這個類大概就太長了。類名越含混,該類越有可能擁有過多的權責。

    ——《Clean Code》

  • 內聚

  • 內聚的含義是,類的每一個字段都應該被某個(些)方法所使用到。如果不能達到這個結果,應該考慮是否類的字段應該拆分出去成為新的類。

  • 嚴格控制訪問權限,注意信息隱藏,OCP

  • 訪問權限應該能小則小。能 private 就不要 package,能 package 就不要 protected。這樣做能使我們更好的遵循 OCP 原則。最穩定的系統,是從不修改的系統。

    2. 函數

  • 盡可能小

  • 經過漫長的試錯,經驗告訴我,函數就應該小 ——《Clean Code》

    應該控制在 10 行以內,至多 20 行,除非是細節代碼。這是完全可以做到的,做不到的原因可能有:函數功能太多,職責不單一;函數抽象層次劃分不清;語言支持不夠等。前面已經說過,做一件事大概也就 2~5 步,每一步一個函數,加上可能的條件判斷,10 行是一個比較合理的數字。而且,函數越小,功能越集中,越便于取一個好名字。

  • 單一職責

  • 一個函數只做一件事。這一點很容易理解,難的是我們如何確定函數做的那件事是什么。一千個讀者就有一千個哈姆雷特,同樣的,不同的人對一個函數的理解也有所不同,對于做一件事的步驟拆分也可能有所不同。對此,一個可靠的判斷準則是:函數的內容(函數體內的代碼)只是做了函數所在抽象層級的步驟,那這個函數就是只做了一件事。函數所在抽象層級,根據對業務的理解,應該用良好的函數名加以示意。

  • 單一抽象層次

  • 一個函數應該只在一個抽象層次上。計算機世界都是層層疊加的,例如:寄存器 -> 高速緩存 -> 主存 -> 硬盤 -> 網絡(可參見《CSAPP》第六章),再如硬件 -> 機器指令 -> 匯編 -> C -> C++ -> JVM -> Java -> Servlet -> Spring -> SpringBoot。嚴格禁止跨層次搞事。我們應該熟悉業務,根據業務上的一次用例,劃分抽象層次,使每一個函數都只在某一個抽象層次上,不要跨層次。還是以把大象裝進冰箱為例:

    最頂層的函數是 f,f 里就只應該有 s1, s2, s3 三個函數。s2a, s2b 里的實現代碼則不應該出現在 f 里。同理在 s2 函數里,只應該有 s2a, s2b 函數,而不應該有抽象層次更低(更具體)的 s2aα, s2aβ 的實現代碼等。

    綠色部分是最低抽象層次的具體實現,這部分是無法拆分,且難以控制代碼行數的,因為有些情況下做一件事就是有很多細節實現步驟。

  • 參數盡量少

  • 最理想是 0 個,其次是 1 個,2 個,最多 3 個參數,不要超過 3 個參數,除非你有非常特殊的理由。——《Clean Code》

    參數帶了極大的語義干擾,而且也難于測試。一個典型的不好的設計,就是用 bool 作為公開函數的參數,因為 bool 變量天然地會使人想到這個函數不會只做一件事,它分情況處理,bool 入參的命名稍有歧義就會使人困惑。例如

    func?GoToWork(raining?bool)?{if?raining?{//?開車去}?else?{//?走路去} }

    更推薦的做法是,將 bool 參數的函數私有,另外公開兩個語義清晰的函數。

    func?WalkToWork()?{goToWork(false) } func?DriveToWork()?{goToWork(true) } //?私有 func?goToWork(raining?bool)?{if?raining?{//?開車去}?else?{//?走路去} }

    任何時候,我們維護代碼,最關心的都是對外可訪問的函數,這些函數應該盡我們所能使其整潔。另一個例子,在 JUnit 里曾有這樣的方法,不知給多少初學者帶來困擾

    assertEquals(expected,?actual)

    對使用者來說,完全沒有必要去記憶兩個參數的相對位置。相較而言,assertJ 里的連貫式接口就要友好得多

    assertThat(actual).isEqualTo(expected)

    golang 里能夠返回多個返回值,但這絕不可以濫用。試看

    func?func1(/*?params?*/)?(string,?string,?string,?string,?string)?{//?函數職責不單一,功能太多 } func?func2(/*?此處多達6個參數?*/)?{//?函數職責不單一,功能太多 }

    這樣多入參、多返回值,給調用方造成很大困擾,調用方需要反復分辨每個參數、返回值的對應關系。不能因為眼前就只有自己調用自己寫的函數而這樣放縱,我們寫的代碼,終究是會由別人接手的。

  • 無副作用

  • 一般而言,函數應該是無副作用的,對于調用方來說,它就是一個黑盒:給定輸入,產生輸出。僅此而已。不要讓調用方去思考我這次調用會不會產生輸出以外的其他結果。例如應該盡量避免這種情況:一個函數,以指針作為參數,返回一個結果的同時,還修改了指針所指向的內容。一個函數的作用,要么是 get,要么是 post,即要么函數無修改的 get 一個結果,要么就是單純修改而不返回修改以外的結果。jdk 里有一個典型的反例,各種集合的 add/set 總返回了一個 bool 值,就會出現這樣的代碼

    //?numbers?is?a?list if?(numbers.add(1))?{// }

    對于新手這可能就是一個讓人迷惑的地方,可見,無副作用也不是絕對的,強如 JDK 也有不得已的折衷處理。

  • if 嵌套不應超過 2 層

  • if 不要嵌套超過 2 層,這初聽起來有些強人所難,仿佛要求每個職業籃球運動員都應該以喬丹的能力作為基準。可人的天性就是不喜歡思考的,喜歡簡單。在此再一次強調統一抽象層次,if 嵌套太多,一定要思考,是不是函數做的事情太多,跨層次在搞事情。我們應該用一些高標準去檢驗自己的代碼,想辦法去滿足,這個過程才會有所成長,否則除了收獲經驗以外,不會有進階的成長(其實人生又何嘗不是如此)。

    消除多層 if 嵌套的一些手段

    • 提前返回,將嵌套 if 鋪陳開來,使不滿足條件的分支提前返回;

    • 碰到第三個 if,直接將其抽取為函數(簡單粗暴);

    • lambda,在 Java 里利用 stream 的扁平化處理,使 filter、map 等語法元素都可以接收簡單的函數,從而避免在 for 里加 if 判斷。對于集合的遍歷處理,都應該盡量先采用 stream 的做法,這種流水線的思想,在一個步驟里就剔除了不滿足條件的對象,然后流轉到下一個步驟。

  • 語義和實現距離不為 0 時應該抽取函數

  • 好的代碼讀起來就應該像自然語言,而不是像程序,這就要求在高抽象層次時,函數應該表達意圖,而只有在葉子結點——抽象層次最低的實現部分才表達實現,這個地方的代碼更像是程序。所以,在代碼中的某個位置,我們本應該表達意圖,卻寫了細節實現代碼,這就應該抽取出函數。以下面這段代碼為例。

    tom?:=?&Person{} if?tom.Age?>=?18?{//?do?your?bussiness }

    一般認為這是表達 tom 是否成年,但實際的業務含義中卻是判斷 tom 是否可以申領 C1 駕照。即使是想表達是否成年,這樣也要使大腦經過一層轉換,由Age >= 18推理一次,才能得出結論這是表達是否成年,這是典型的“代碼 prase 語義”,不要小看這層 parse 對人腦的開銷,特別是所見之處都是這樣的代碼會讓我們的大腦長期忙于“線程切換”活動,造成的思維停頓讓人非常沮喪;此外,如果一個日本人看到這段代碼,一定不會想是表達是否成年這個語義,因為他們的法定成年年齡是 20 歲(2022 年 4 月 1 日起改為 18 歲),這是代碼不靈活的體現。推薦的做法是

    if?tom.isAdult()?{//?do?your?bussiness } func?(p?*Person)?isAdult()?bool?{return?p.Age?>=?18 }

    這樣,在isAdult方法里還可以更改實現,也更靈活,很多時候,如果我們程序寫得好,實現比較靈活,就能夠從容的應對經常變化的需求;如果需求稍微變化一下,現有代碼就頂不住了,就應該思量實現是否足夠好。代碼應該表達意圖,特別是 if 條件分支里,不要讓人再去推理,直接表達語義。就像人走路,相比于一馬平川,我們不會更喜歡岔路;但凡岔路,就應該明確指明路線,而不是在路口打個機鋒,才讓你思考十年然后頓悟才選擇出了某一條路。

  • 童子軍軍規

  • 走的時候,比來的時候干凈一點。代碼中如果我們能經常注意這一點,那我們每時每刻都在改善代碼。世界是朝著熵增的方向發展的,譬如一個房間,即使我們完全不去干擾它,久而久之它也會變得更加混亂,代碼也是這樣,它終究會變得越來越混亂、難以修改、難以維護。如果我們不注意這一點,反而每次來都扔一點垃圾,久而久之就會成為“破窗”直至“破樓”。

  • hardcode

  • 任何時候都不應該在代碼中直接出現 hardcode,hardcode 難以表達語義,且難以管理。

    3. 命名與注釋

    命名是一個哲學問題,我們所知的一切,都是命名,存在、宗教、知識、倫理...沒有命名,我們所知的一切所謂知識都將崩塌。

    There are only two hard things in Computer Science: cache invalidation and naming things. ——Phil Karlson

    “計算機世界只有兩個難題:緩存失效和命名。”(可讀一讀《CSAPP》關于存儲層次結構的描述,對此會深有體會。)

    坊間流傳著一句話,給變量命名猶如給自己親女兒命名一般,只因如此,就不會隨意命名了。命名的一般原則無外乎完整、簡潔、準確等。

  • 顧名思義、望文知義、無歧義

  • 清楚明白無歧義地表達含義,不要讓別人猜你的意思。在 API 設計里,有一條原則即是“Don't Let Me Think”,命名也應該如此,乃至日常工作溝通中也應當如此。

  • 名副其實

  • cat := &Dog{}?

  • 表達語義,避免誤導

  • userList實際實現是一個 Set,users 這個命名會更好,語義更清晰,userList 有一些語義干擾。命名不應該表達實現(如 List 實現,數據結構等),而應該表達語義。

  • 使用讀得出來的名字,謹慎使用縮寫

  • 人看代碼,實際是在默讀代碼,包括你現在看到這句話的時候,心里也是在默念出來的。如xxCmd這樣的命名,一定會在腦海中多了一次 parse,對于一些更不常見的縮寫,這種情況更嚴重。前面提過,這種腦內 parse 會使大腦忙于“線程切換”,思維停頓更是讓人沮喪。

  • 團隊統一業務術語

  • DDD 的一個重要理念就是同一術語,在一個團隊內部就應該統一術語,從運營產品到開發測試等,都應該對某一個業務專有詞不產生任何歧義。我見過太多因為產品和開發對某一個詞的理解不同而“大打出手”的事。

  • 注釋

  • 好的代碼是自注釋的。

    命名雖然重要,但也無需發展成為圣戰。

    4. 單元測試

    應該重視單元測試。單元測試,保證軟件質量和代碼質量。單元測試是我們所寫函數的第一個調用者,如果發現單元測試很難寫,那不用說,函數實現絕對是有問題的,或者抽象層次劃分不清,或者依賴復雜等。如果連我們自己調自己的方法都用得這么不爽,那可想而知其他調用者,特別是網絡接口。這是為什么單元測試可以保證代碼質量,它可以檢驗我們的代碼是否寫得足夠好。

    單元測試對于修改代碼或重構的重要性無可替代,對于擁有一組完善單測的函數,我們可以隨意更改,只要讓修改后的函數通過單測,就幾乎是安全修改的,單元測試鋪了一張安全網,讓我們像走鋼絲一樣地寫代碼不至于失足跌入深淵萬劫不復。

    關于單元測試有很多實踐,最著名的可能莫過于 TDD,我們雖不至于按 TDD 的實踐來開發,但我們應該善用單元測試,來檢驗我們的函數實現是否合理,實現得好的函數,單測一定是好寫的,逆否亦然。

    一些 tips:

    • 不能依賴真實依賴,這是大忌。如依賴真實數據庫且數據庫出錯,并不能檢驗單測所測函數邏輯失敗,而是外部造成的,應該 mock,且對一般對象也應該盡量使用 mock 對象;否則即為集成測試;

    • 路徑應該盡可能全;

    • 不能有條件分支,任何條件分支都應該新開單測;

    • 單測也應該像業務代碼一樣,干凈整潔;

    • realBug 測試是必要的,發生過一次的事情很有可能會反復發生,我們選擇題第一次選錯了,第二次還是很可能選擇上次的那個錯誤答案;

    • ...

    其他話題

    以下這些話題,單獨拎出來都是一個很大的主題,這里只是拋磚引玉,簡單談談一些和整潔代碼相關的感悟和實踐,實是整潔代碼需要各個方面的努力,而非僅代碼一途用功。

    心智負擔與復雜

    Complexity is caused by two things: dependencies and obscurity.

    軟件開發的復雜性由兩樣東西帶來:依賴和晦澀。這兩者都會加重心智負擔。消除心智負擔一定程度上意味著增加可讀性和可維護性。

    其實我們所做的一切,都是在馴服復雜度。人腦終究是有限的,我們眼所能見、腦所能別的資源幾乎都是有限的。馴服復雜度,代碼寫好了,升職加薪,業余時間沒有 bug 找上門,提高生活質量,我們所做的一切不就是為了這個嗎?

    復雜是我們軟件生涯的一生之敵

    分層分包

    分層是除“模塊化”之外最古老的架構模式,馮諾依曼計算機模型是模塊化的架構,但同時計算機世界也是層層疊加的。分層分包的本質就是隔離,人處理難題的能力是有限的,無法同時處理很多復雜的事情,所以不把所有東西都放在同一層次,譬如行政體系也是分層的。隔離使得各個層次職責更清晰,更容易管理。

    分層的原則是只能上層調用下層,而不能反過來,反之容易導致循環依賴。分包的原則是,同一個包中的對象天然是親和的,同時對包外的對象是不親和(隔離)的

    從分層的理念理解,則 controller/api 層 的 request 不應該一直傳遞到 service 層甚至是 dao 層,然而這種現象卻是非常常見。業務層不應該對界面層有所了解,而是相反,界面層調用業務層來完成一次用戶用例。凡是進入業務層,就不應該有界面層的對象,而應該在界面層轉換成業務對象,進而使業務層只處理它所能知的業務對象。這種跨層次的信息傳遞,無異于鄉長直接向省長匯報工作。

    傳統 MVC 的分層對于簡單業務而言,是簡單實用的。但是其對于復雜業務系統的架構能力十分有限,一個 service 包里有上百個 xxxService 類,業務表達能力有限,如果所有對外服務都可以叫做 service,那為何要區分餐廳、醫院、商場,統一叫服務不就好了?而且很多時候,往往就是一些無法準確劃分職責的類干脆就合并到 Service 類里,這讓 Service 類成了一個大雜燴直至成為 God Class,最終退化成過程式代碼,只是機械的代碼堆積,沒有層次分明、職責分明的對象,沒有設計感。

    對于業務復雜的系統,DDD 微服務經典四層分層是一個更好的實踐,重視業務、重視 OO,整個系統設計感十足,對象林立,可以做一些了解。但是對于業務簡單的系統,則不應該為了炫技而使用技術。因地制宜,學會取舍。

    此外,關于 dao,業務復雜情況下應該避免使用。dao 的表達能力同樣很弱,dao 里的方法很難表達意圖,語義表達能力很弱,findByXXX 實際是沒有業務語義的,例如 findByAge 接受參數 18,還是上面的例子,并不是選擇成年的業務意義。此外 dao 難以管理。例如一個 dao 里有上百個 findByXXX 方法,如果業務需要新增方法,一般最省事的做法就是直接又加一個 findByXXX 方法,這樣下去 dao 會越來越膨脹并趨于崩壞。業務復雜情況應該使用 repository,repository 通過組合規格(specification)來表達查詢語義,repository 是倉儲的概念,類似一個 ADT,只有有限幾個經過仔細設計的方法,類比一個 map 就理解了。關于更多為何不使用 dao 而應該使用 repository 的知識,可參考 https://thinkinginobjects.com/2012/08/26/dont-use-dao-use-repository/

    設計原則

    遵循良好的設計原則,能使代碼更整潔,當然意義不僅于此。有關設計原則的資料很多,我們也應該對此有所了解。常見設計原則如:

    • SOLID

    • ADP

    • REP

    • CCP

    • CRP

    • SDP

    • SAP

    • DRY

    • KISS

    • YAGNI

    • SLAP

    • POLA

    • LoD

    代碼的非功能特性

    只完成功能的代碼,是最基礎的代碼。好的代碼還應該盡量完成代碼的非功能特性,有興趣可以了解下,不外乎:

    • 可操作性

    • 健壯性

    • 可測試性

    • 可維護性

    • 易用性

    • 可重用性

    其實還有些主題是無法避而不談的,如錯誤處理,但限于篇幅和能力,只能推薦讀兩遍《Clean Code》。

    最后,人生不過是“看山是山,看山不是山,看山仍是山”,代碼也是如此,不要著相。

    - END -


    看完一鍵三連在看轉發,點贊

    是對文章最大的贊賞,極客重生感謝你

    推薦閱讀

    程序員必讀的經典書單!快來領當當大額優惠券!全場半價+大額優惠劵!

    深入理解重要的編程模型

    深入理解編程藝術之策略與機制相分離

    超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

    總結

    以上是生活随笔為你收集整理的如何编写好的代码?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 一级在线 | 91美女片黄在线观看 | 国产老头老太作爱视频 | 国产午夜片 | 先锋影音一区二区 | 蜜桃传媒一区二区亚洲 | 黄色录像大片 | 青青青免费在线视频 | 国产精品自产拍在线观看 | 欧美与黑人午夜性猛交久久久 | 久草午夜 | 无码精品人妻一区二区三区漫画 | 国产成人无码精品久久二区三 | 香蕉国产精品 | 国产黄色在线播放 | 搞黄网站在线观看 | 精品人体无码一区二区三区 | 韩国伦理av| 久操视频免费观看 | 色婷婷aⅴ一区二区三区 | 久久免费成人 | 杨幂一区二区三区免费看视频 | 成片免费观看视频大全 | 国产精品久久久久野外 | 亚洲色图插插插 | 在线观看成人 | 久久精品视频6 | 国产绳艺sm调教室论坛 | 黄色一级视频 | 欧美成人一区二免费视频软件 | 波多野结衣 一区 | 精品一区二区三区不卡 | 小珊的性放荡羞辱日记 | av在线播放网站 | 人妻精油按摩bd高清中文字幕 | 伊人久久久久久久久久久久久 | 久久国产色av免费观看 | av看片| 国产欧美日韩高清 | 亚洲欧美成人一区二区三区 | 91免费 看片 | 精品一区二区三区国产 | 特黄1级潘金莲 | 91九色网站| 亚洲精品视频免费看 | 刘玥91精选国产在线观看 | 福利电影一区二区 | 1024精品一区二区三区日韩 | 九九九九九热 | 性中文字幕 | 污视频在线观看网址 | 黄色三级在线 | www.日韩 | 欧美在线一二三四区 | 午夜精品视频一区二区三区在线看 | 国产伦精品一区二区三区免费视频 | 人妻无码久久一区二区三区免费 | 超碰com | 韩国av三级| αv在线 | av网址导航 | 国产福利在线视频观看 | 亚洲精品国产精品国自产观看 | 国产乱码精品一区二区三 | 国产有码在线观看 | 中文字幕亚洲色图 | 激情小视频在线观看 | 成人在线免费视频 | 国产精品成人免费视频 | 3p在线播放 | 丰满熟妇人妻av无码区 | 午夜在线一区 | 欧美乱妇狂野欧美在线视频 | 色女综合 | 综合一区| 男女www视频| 中文字幕色网 | 狠狠爱夜夜爱 | 成人欧美精品一区二区 | 涩涩99| 中文字幕第一页在线播放 | 91豆花视频 | 九色91 | 色干综合| 久久久999 | 玖玖爱资源站 | 一本视频在线 | 四虎永久在线精品免费网址 | 日本在线资源 | 免费无码毛片一区二区app | 亚洲青色在线 | 久久最新 | 成人在线观看国产 | 亚洲视屏| 日本不卡一区二区三区视频 | 最新色网站 | 九九在线视频 | 亚洲永久无码7777kkk | 人人cao|