浏览 1794 次
锁定老帖子 主题:《Clean Code》总结 异常
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-03-14
最后修改:2010-03-14
1.使用异常而不是错误码
如果使用错误码,调用者,必须在方法调用后立即检查结果,如果多次调用都放回错误码,就会造成复杂的多层嵌套结构。 if (deletePage(page) == E_OK) { if (registry.deleteReference(page.name) == E_OK) { if (configKeys.deleteKey(page.name.makeKey()) == E_OK){ logger.log("page deleted"); } else { logger.log("configKey not deleted"); } } else { logger.log("deleteReference from registry failed"); } } else { logger.log("delete failed"); return E_ERROR; } 2.使用uncheck异常 java世界就checked exception的优劣争论了很久。没有checked异常的也能构建robust的程序。为了robust而使用checked异常的代价太高了。checked异常最大的问题在于它是的程序违反了 开放/封闭原则 调用者不得不捕捉异常或者声明抛出异常。如果底层的异常修改了,高层代码也要修改。如果异常在较高层次处理,就会造成一串的修改。 3.为了调用者的方便,封装异常调用代码 很多标准库或者第三方库的方法调用会抛出多个checked异常,对一长串异常处理的代码显得太冗长,而直接捕捉Exception又会丢失很多细节。一个解决方法就是,使用单独的类或方法封装抛出异常的方法调用,做一些处理后抛出unchecked异常,方便上层调用。 ACMEPort port = new ACMEPort(12); try { port.open(); } catch (DeviceResponseException e) { reportPortError(e); logger.log("Device response exception", e); } catch (ATM1212UnlockedException e) { reportPortError(e); logger.log("Unlock exception", e); } catch (GMXError e) { reportPortError(e); logger.log("Device response exception"); } finally { … }做如下封装 public class LocalPort { private ACMEPort innerPort; public LocalPort(int portNumber) { innerPort = new ACMEPort(portNumber); } public void open() { try { innerPort.open(); } catch (DeviceResponseException e) { throw new PortDeviceFailure(e); } catch (ATM1212UnlockedException e) { throw new PortDeviceFailure(e); } catch (GMXError e) { throw new PortDeviceFailure(e); } } } 高层代码只需要处理DeviceResponseException。这样做也使得第三方代码的传播度更小,也更方便mock方法调用。 4.不使用异常处理正常逻辑,比如下面的代码 try { MealExpenses expenses = expenseReportDAO.getMeals(employee.getID()); m_total += expenses.getTotal(); } catch(MealExpensesNotFound e) { m_total += getMealPerDiem(); } 异常弄乱了正常的逻辑。解决方法是让ExpenseReportDAO始终返回MealExpenses,如果MealExpenses not found,可是返回一个特殊的MealExpenses public class PerDiemMealExpenses implements MealExpenses { public int getTotal() { // return the per diem default } } 这叫着SPECIAL CASE PATTERN [Fowler],You create a class or configure an object so that it handles a special case for you. 5.不要返回Null。 方法调用如果允许放回null,会大大增加调用者的复杂度。可以考虑抛出异常,或者使用Null Object或者特殊的对象。例如 List<Employee> employees = getEmployees(); if (employees != null) { for (Employee e : employees) { totalPay += e.getPay(); } } ------ public List<Employee> getEmployees() { if (.. there are no employees ..) return Collections.emptyList(); } 如果没有Employee,就返回一个空的List,这样调用者可以不用做特殊的处理。 6.不要传递null到方法。 如果参数可为null,方法不得不做必要的检查,代码会很冗余,而且没有很好解决方案。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |