寫在前面
這個文章本來沒打算寫,直到經歷了幾次代碼評審會議之后,我意識到自己編碼方式還不成系統,仍然需要進行系統化的學習,掌握前輩們總結出的最適用的規律無疑是一種好的方式。恰好很早之前就收藏了這本代碼整潔之道,便決定趁著閑暇之際閱讀總結一下,如果想系統學習的話建議還是讀書,本文檔只是作為自己的記錄用。
一個人的職業素養體現在解決問題的方式、步驟以及反思的程度,而不在于這個問題本身的難度。思考一個問題:一個技術人員要具備哪些素質可以被認為是專業人員呢?如果還不具備需要如何改變才能被視為專業人士呢?
整潔代碼
一、為什么要寫糟糕的代碼?
每個人都有自己的原因,相信很多人都會想著等有時間的話再進行代碼優化,但是要記住一句話:稍后等于永不。
二、混亂代碼的代價?
后續難以維護和修改,生產力和時間呈現負相關。
三、什么是整潔的代碼?
整潔的代碼只做好一件事:每個類、每個函數、每個模塊都專注于一事,完全不受四周細節的干擾和污染。
更全面的概括是:減少重復代碼、提高表達力、提早構建簡單抽象。
更具體的實現:請接著往下看吧!
更好的變量命名
一、見名知意
二、抽象工廠:接口不要命名為IShapeFactory,前導字母對于用戶來說其實是干擾,用戶只需要知道那是個抽象工廠,建議使用CShapeFactory或許體驗更好
三、類名要用名詞,方法要用動詞,詞性相近的get、fetch這種詞不應出現在一起,可以添加后綴getNumber、fetchData實現相同的效果
四、別害怕長名字:使用描述性的名稱,哪怕比較長也比短而令人費解的名稱好
更好的函數
一、函數的結構本質上要短小、再短小,以不容納if/else if/else嵌套結構為目標
二、只做一件事:正如前面所說,函數只做好一件事就足夠了,標志就是“看是否還能拆出一個函數,該函數不僅只是單純地重新詮釋其實現”
三、每個函數一個抽象層級:代碼一般是“自頂向下”的閱讀順序,每個函數后面跟著的應該是下一抽象層級的函數
[抽象層級:getHtml函數位于較高抽象層,pagePathName = pathParser.render(pagePath)位于中間抽象層,.append(" ")則位于較低抽象層]
四、switch語句:天生就需要做N件事,但是可以將其放置在較低抽象層級,但是當出現新的類型時會違反“單一權責原則、開放閉合原則”,此時最好創建多態對象
//原文中:對于每個case分支進行單獨處理,添加新類型不必修改原來的代碼增加新的處理類即可 functiongetName(name){ switch(name){ case'ming': returnnewClassMing(name); case'hu': returnnewClassHu(name); case'uzi': returnnewClassUzi(name); default: thrownewClassCommon(name); } } //我更喜歡用另一種方法:修改只需要在對象里修改即可,且提高了函數的簡潔性 constnameCollectionUtils={ ming:newClassMing('ming'); hu:newClassHu('hu'); uzi:newClassUzi('uzi'); } functiongetName(name){ returnnameCollectionUtils.hasOwn(name)?nameCollectionUtils[name]:newClassCommon(name) }
五、函數參數最多不多于兩個:包括輸入參數和輸出參數
六、無副作用:函數內部不要做出未能預期的改動,不要對外部產生影響
七、使用異常替代返回錯誤碼:使用try...catch替代多層級的if嵌套,永遠走在主路上,不要過多考慮邊界,這樣可以讓你一直保持思維連貫
八、錯誤處理單獨抽出:這一條我認為可以視情況而定,畢竟抽出僅僅是為了美觀
九、別重復:多個函數使用的相同邏輯的代碼一定要抽出,可以參考面向對象的基類,前端開發中的面向組件編程、面向模塊編程也是這種思想
注釋&格式
每個人有每個人的習慣,采取一些通用準則即可,畢竟如何太過離譜在公司是會挨打的~
錯誤處理
也沒有什么固定的章程,最好采取try...catch優先的原則
邊界
總結而言,使用自己可以控制的代碼
單元測試
現在的互聯網企業絕大多數都是敏捷式開發,很少有能遵守測試驅動原則的公司,而且為了保證進度很少會有技術團隊會去要求單元測試,所以這一條仁者見仁吧,個人認為這一項的實際實現只能是一個比較美好的愿景。
類
一、類的組織:按照下面的順序,不要暴露出內部屬性,利用方法達到同樣的目的
classDemoOrganization{ staticsname='sname' privatepname='pname' private_pname='_pname' protectedtname='tname' publicgetPublicName(){ returnthis.pname } private_getPrivateName(){ returnthis._pname } }
二、單一權責原則(SPR):類或模塊應有且只有一條加以修改的理由,實現了這個原則的類更易得到復用
三、保持內聚性:類中定義的變量應被盡可能多的方法使用到,如果不能滿足的話就把使用到變量的函數拆分成小類
四、開放封閉原則(OCP):類應當對擴展開放,對修改封閉,通過子類化手段可以實現新功能的添加的同時不觸及其他類
五、依賴倒置原則(DIP):類應當依賴于抽象而不是依賴于具體細節
六、解耦:不同方法和模塊間不要互相產生影響,即“分而治之”、“化整為零”
系統
一、構造和使用分開:構造的細節應隔離與應用程序代碼之外,使用者只能獲取構造者想讓使用者獲得的東西
二、設計時要能滿足從簡單到復雜的更新迭代
迭進
總結上述,只要遵守以下原則,就可以得到一個具有良好設計的可迭進的程序:
運行所有測試
不可重復
表達了程序員的意圖
盡可能減少類和方法的數量
以上規則按重要程度排列
并發編程
首先要了解“線程”這個概念:CPU調度的最小單位,區別于“進程”是資源分配的最小單位。區別見下方表格:
分類 | 數據共享 | 消耗資源 | 是否影響兄弟程序 | 最大可擴展維度 | 是否有鎖 |
---|---|---|---|---|---|
進程 | 難 | 多 | 否 | 多機 | 是 |
線程 | 簡單 | 少 | 可能影響所在進程 | 多核 | 否 |
如果說對象是過程的抽象,那么線程是調度的抽象
前端使用的js語言是瀏覽器腳本語言,最主要的用途是和用戶互動和操作DOM,這決定了js只能是單線程否則會產生復雜的同步問題,但是js仍然可以模擬并發執行,具體實現自行查詢相關資料
當前還沒學習到并發編程的語言,以后碰到再補充學習
重構
這個模塊我認為是最重要的模塊,甚至比怎么去編寫新的程序更重要,因為一個公司的沉積項目的數量是巨大的,很可能會對其中幾個甚至更多進行重構(還是因為之前代碼寫的太爛無法維護),所以重構中需要注意的點也要有一個清晰的認知。
只需要遵守一條原則:簽入的代碼比簽出的更整潔。
寫在最后
以上是我從前端角度總結的從這本書中得到的一些收獲,但是每個人都會有每個人自己的理解,所以還是推薦自己去讀一遍這本書,不需要多精細只要熟悉一下這些概念提出來的場景,相信會有更大的收獲。
審核編輯:劉清
-
SPR
+關注
關注
0文章
20瀏覽量
11512 -
DIP
+關注
關注
0文章
242瀏覽量
30254 -
OCP
+關注
關注
0文章
80瀏覽量
16475 -
DOM
+關注
關注
0文章
18瀏覽量
9601
原文標題:常說的代碼整潔到底是什么?
文章出處:【微信號:eng2mot,微信公眾號:汽車ECU開發】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
低代碼與傳統開發的區別 低代碼與無代碼開發的區別
低代碼在敏捷開發中的應用
代碼整潔之道-大師眼中的整潔代碼是什么樣
![<b class='flag-5'>代碼</b><b class='flag-5'>整潔</b>之道-大師眼中的<b class='flag-5'>整潔</b><b class='flag-5'>代碼</b>是什么樣](https://file1.elecfans.com//web2/M00/05/C9/wKgZombesjCAGIWdAAHN7xWKtsQ450.png)
![](https://file.elecfans.com/web2/M00/A9/3D/pYYBAGR3Pi6AHWcaAAASvCKK-04863.png)
國內低代碼平臺推薦--萬界星空科技低代碼平臺
![國內低<b class='flag-5'>代碼</b>平臺推薦--萬界星空科技低<b class='flag-5'>代碼</b>平臺](https://file1.elecfans.com/web2/M00/FD/09/wKgZomaXkZyAEKqGAAc6Dd_-9ZQ961.png)
該如何提高代碼容錯率、降低代碼耦合度?
![該如何提高<b class='flag-5'>代碼</b>容錯率、降低<b class='flag-5'>代碼</b>耦合度?](https://file.elecfans.com/web2/M00/20/B3/pYYBAGGfNNmAK-PZAAJsGM5Cgk0227.jpg)
評論