看完《代碼整潔之道》以後我受益不淺,但等到本身實踐時卻很難按照書中給的建議編寫出整潔的代碼。一方面是規則太多,記不住,另外一方面書上引用了大量示例代碼對這些規則進行佐證,在我記不住時亦不方便查閱。因而我把書中的規則摘了出來並加以必定的解釋,閒暇時候多過幾遍,但願這些規則時刻警示我,成爲個人習慣。php
想看此書卻還沒開始的人也能夠從這篇筆記出發,對筆記中列出的規則有疑問再翻書找答案,相信會比直接啃書來的快一些。java
ps: 未必要嚴格遵循書中的規則,代碼不是八股文。程序員
if(set("username", "unclebob")) { ... }
的含義模糊不清。應該改成:算法
if (attributeExists("username")) { setAttribute("username", "unclebob"); ... }
返回錯誤碼會要求調用者馬上處理錯誤,從而引發深層次的嵌套結構:編程
if (deletePate(page) == E_OK) { if (xxx() == E_OK) { if (yyy() == E_OK) { log(); } else { log(); } } else { log(); } } else { log(); }
使用異常機制:session
try { deletePage(); xxx(); yyy(); } catch (Exception e) { log(e->getMessage()); }
try/catch代碼塊醜陋不堪,因此最好把try和catch代碼塊的主體抽離出來,單獨造成函數數據結構
try { do(); } catch (Exception e) { handle(); }
建立一個與註釋所言同一事物的函數便可併發
// check to see if the employee is eligible for full benefits if ((employee.falgs & HOURLY_FLAG) && (employee.age > 65))
應替換爲app
if (employee.isEligibleForFullBenefits())
闡釋。把某些晦澀的參數或者返回值的意義翻譯成可讀的形式(更好的方法是讓它們自身變得足夠清晰,可是相似標準庫的代碼咱們沒法修改):less
if (b.compareTo(a) == 1) //b > a
// don't run unless you have some time to kill
能用函數或者變量表示就別用註釋:
// does the module from the global list <mod> // depend on the subsystem we are part of? if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem())
能夠改成
ArrayList moduleDependees = smodule.getDependSubsystems(); String ourSubSystem = subSysMod.getSubSystem(); if (moduleDependees.contains(ourSubSystem))
///////////////////// Actions //////////////////////////
右括號註釋
try { while () { if () { ... } // if ... } // while ... } // try
若是你想標記右括號,其實應該作的是縮短函數
/* add by rick */
源代碼控制工具會記住你,署名註釋跟不上代碼的演變。 if (xx == yy) z = 1;
對象:暴露行爲(接口),隱藏數據(私有變量)
數據結構:沒有明顯的行爲(接口),暴露數據。如DTO(Data Transfer Objects)、Entity
class C的方法f只應該調用如下對象的方法:
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
異常處理很重要,但若是異常處理四處分散在代碼中 致使邏輯模糊不清,它就是錯的。
try { MealExpendses expenses = expenseRepotDAO.getMeals(employee.getID()); m_total += expenses.getTotal();// 若是消耗了餐食,計入總額 } catch (MealExpensesNotFound e) { m_total += getMealPeDiem();// 若是沒消耗,將員工補貼計入總額 }
異常打斷了業務邏輯。能夠在getMeals()裏不拋異常,而是在沒消耗餐食的時候返回一個特殊的MealExpense對象(PerdiemMealExpense),複寫getTotal()方法。
MealExpendses expenses = expenseRepotDAO.getMeals(employee.getID()); m_total += expenses.getTotal(); publc class PerDiemMealExpenses implements MealExpenses { public int getTotal() { //return xxx; //返回員工補貼 } }
將第三方代碼乾淨利落地整合進本身的代碼中
四條規矩幫助你建立優良的設計
模板方法模式是消除重複的通用技巧
// 原始邏輯 public class VacationPolicy() { public void accrueUSDivisionVacation() { //do x; //do US y; //do z; } public void accrueEUDivisionVacation() { //do x; //do EU y; //do z; } } // 模板方法模式重構以後 abstract public class VacationPolicy { public void accrueVacation() { x(); y(); z(); } private void x() { //do x; } abstract protected void y() { } private void z() { //do z; } } public class USVacationPolicy extends VacationPolicy { protected void y() { //do US y; } } public class EUVacationPolicy extends VacationPolicy { protected void y() { //do EU y; } }