svn如何隐藏代码路径_程序员课堂—如何通过改善代码风格来消灭隐藏bug
寫在前面:一名有三年Android開發經驗的女程序員(歡迎大家關注我 ~期待和大家一起交流和學習Android的相關知識)
正如食物腐爛之前,可能會發出異味。當代碼存在隱藏問題時,代碼也會表現出一些異狀,我們稱之為代碼異味(code smell),它存在于整體結構和代碼設計階段,暗示代碼塊或通用的編程模式中可能存在更深層次的問題。
代碼異味通常被認為是暗示代碼段需要重構的標志,但這并不是說代碼有bug或者是無用的 。通常情況下,存在代碼異味的代碼塊也能夠運行的很好,但是一般難以維護和擴展,這就會導致一些技術問題,特別是在大型項目中,這種現象更加明顯。
那么常見的代碼異味有哪些呢?又要如何解決呢?下面我們將重點介紹10種最常見的代碼異味以及如何對它們進行“除臭”。
1.緊耦合
存在的問題
緊耦合是指兩個對象相互依賴于彼此的數據或函數,如果修改其中一個對象,那么另一個對象也需要修改。當兩個對象過于緊耦合時,修改代碼可能會是一場噩夢,同時更有可能在每次修改時引入bug。
例如:
在這種情況下,Worker類和Bike類緊密耦合。如果有一天你想開車去上班而不是騎自行車?你必須進入Worker類,將所有與Bike類相關的代碼替換為與Car類相關的代碼。這就會變得很混亂,很容易出錯。
解決方法
你可以通過添加一個抽象層來降低耦合程度。在這種情況下,Worker類不僅可以騎自行車,還可以開車,還可以開卡車,甚至還可以騎摩托車。這些都屬于交通工具,不是嗎? 所以可以創建一個交通工具接口,根據你的需求,允許插入和修改不同類型的交通工具。
例如:
2.上帝對象
存在的問題
上帝對象是指包含太多變量和函數的大型類或模塊。“知道得太多”和“做得太多”都會造成一些問題,原因有以下兩點。首先,其他類或模塊會變得過分依賴于數據(緊密耦合)。其次,由于所有代碼都擠在同一個地方,使得整體結構雜亂無章。
解決方案
取一個上帝對象,然后根據它存在的問題來分離它的數據和函數,再將這些分組轉換成對象。相較于上帝對象,分解為許多小對象可能會更好。
例如,假設你有一個巨大的User類:
您可以將其轉換為以下內容的組合:
這樣在下次需要修改登錄過程時,就不必通過巨大的User類,而是通過易于管理的Credentials類!
3.長函數
存在的問題
顧名思義,長函數是指函數太長了。雖然沒有一個特定的數字表示多少行代碼對于一個函數來說“太長”,但當你看到這個函數時,你就會知道它是不是太長。這幾乎是上帝對象問題的一個更嚴重的版本,一個長函數包含了太多的功能實現。
解決方案
長函數應該被分解成許多子函數,其中每個子函數被設計為處理單個任務或問題。理想情況下,原始的長函數將變成一個子函數調用列表,從而使代碼更清晰,更易于閱讀。
4.參數過多
存在的問題
函數或類的構造函數擁有太多的參數會造成一些問題,原因有以下兩點。首先,這會使得代碼不易閱讀,測試也更加困難。其次,更重要的是,這意味著該函數的功能太模糊,承擔著太多功能的實現。
解決方案
盡管“過多”對于參數列表而言是主觀的,但我們建議對任何超過3個參數的函數保持關注并盡量避免。當然,有時候一個函數有5個甚至6個參數也是允許的,前提是有合理的理由。
大多數情況下,不存在一種方法能更好地將該函數分解為兩個或更多不同的函數。與“長函數”不同的是,這個問題不能僅僅通過用子函數替換代碼來解決 ,因為是函數本身需要分解為單獨的子函數,而每個子函數都需要包含各自的功能。
5.命名模糊的標識符
存在的問題
一個或兩個字母的變量名、無明顯意義的函數名稱、過分修飾的類名、使用變量類型標記的變量名稱(例如,b_isCounted表示布爾變量),最糟糕的是,在一個代碼中混合使用不同的命名規則,所有這些都將導致代碼難以閱讀,難以理解和難以維護。
解決方案
為變量,函數和類命名是一個難學的技能。如果你正在參與一個已有的項目,請仔細觀察現有的標識符命名方式。如果存在命名風格指南,那么請記住它并時刻遵守它。如果是新項目,就可以考慮形成自己的命名風格并且堅持下去。
一般而言,變量名稱應該簡短但具有描述性。函數名通常應該至少有一個動詞,并且函數名稱應該表現出該函數的功能,但是不要使用太多的單詞,類名也是如此。
6.幻數
存在的問題
當你正在瀏覽一些其他人寫的代碼,這時你發現了一些硬編碼的數字。它們也許是if語句的一部分,或者是一些難以理解的計算的一部分,看起來沒什么意義,而你需要修改該模塊,但卻無法理解這些數字的含義,這會使你非常苦惱。
解決方案
在編程時,應該不惜一切代價避免這些所謂的“幻數”。硬編碼數字在寫的時侯是有意義的,但是它們很快就會失去所有含義 ,特別是當其他人試圖維護你的代碼時。
其中一種解決方法是留下數字的注釋,但更好的選擇是將幻數轉換為常量變量(用于計算)或枚舉(用于if語句和switch語句)。通過給幻數起一個名字,代碼可讀性一目了然,同時也不太容易出現錯誤。
7.深度嵌套
存在的問題
有兩種主要的語句可能造成深度嵌套代碼:循環和條件語句。深度嵌套的代碼并不總是很糟糕,但可能會產生問題,因為它很難理解(特別是變量沒有被很好地命名的情況下),甚至更加難以修改。
解決方案
如果你發現自己正在編寫一個雙重,三重甚至四重for循環,那么代碼將可能試圖在超出自身的范圍外查找數據。所以你應該提供一種方法,使之可以通過包含該數據的對象或模塊函數調用來請求數據。
另一方面,深層嵌套的if語句通常表明你試圖在單個函數或類中處理過多的邏輯代碼塊。事實上,深層嵌套和長函數往往是同時出現的。如果你的代碼有大量的switch語句或嵌套的if-then-else語句,你可能需要實現一個狀態機或策略模式。
8.未處理異常
存在的問題
異常的功能是非常強大的,但卻容易被濫用。不正確地使用throw-catch語句可能會導致調試難度大幅增長。例如,忽略或掩蓋捕獲的異常。
解決方案
不要忽略或掩蓋捕獲的異常,而是要打印出異常的及其調用信息,這樣調試人員才可以發現錯誤。如果你的程序悄無聲息地運行失敗,那么將來你可能就要頭痛不已了!此外,我更傾向于輸出特殊的異常信息而非所有異常。
9.重復的代碼
存在的問題
你在程序多個無關部分執行相同的邏輯代碼塊,然后發現需要修改該邏輯代碼塊,但是卻不記得所有執行該代碼塊的地方,假設最終你只修改了5個位置,而實際上有8個位置的代碼塊需要進行更改,這就會導致結果出現錯誤。
解決方案
解決重復代碼問題的首要選擇是轉化為函數。假設你正在開發一個聊天應用程序,你是這樣編寫的:
在代碼中的其他地方,你發現你需要執行一個相同的“這個用戶在線嗎?”檢查。這時不要復制粘貼代碼塊,而是把它放到一個函數中:
這樣在代碼的任何地方,你都可以使用isUserOnline()函數進行檢查。如果你需要修改此邏輯代碼塊,就只需要修改該方法,再將其應用于所有調用該方法的地方就可以了。
10.缺乏注釋
存在的問題
代碼在任何地方都沒有注釋。沒有函數的功能注釋,沒有類的使用概述,沒有對算法的解釋等等。有人可能會說,寫得好的代碼不需要注釋,但事實上,即使是寫的最好的代碼也不如注釋更容易被理解。
解決方案
易于維護的代碼塊應該是代碼寫得足夠好以至于不需要注釋,但它仍然有注釋。在寫注釋的時候,要記住你的目的是為解釋代碼塊為什么存在,而不是解釋代碼塊在做什么。注釋能幫助你更好的理解自己和他人的代碼,減少工作量,所以不要忽視他們。
如何編寫風格良好的代碼
顯而易見,大多數不規范的代碼都是由于對良好的編程原則和代碼風格的忽視。假如你能夠嚴格遵守DRY原則(Don't repeat yourself)就能消除大部分的重復代碼,而掌握單一職責原則就可以避免創造巨大的上帝對象。
千萬不要輕視這個問題,如果連你都無法一目了然地看懂自己的代碼,更何況其他人呢?
每天和大家分享和程序員有關的文章,促進大家一起學習和交流,油吧程序員!
總結
以上是生活随笔為你收集整理的svn如何隐藏代码路径_程序员课堂—如何通过改善代码风格来消灭隐藏bug的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql in 很大 优化_【转】my
- 下一篇: mysql o转数字排序_mysql学习