在Robert Martin的清洁代码书中,有一个Java示例,说明何时使用special case pattern。而不是写这个:
try {
MealExpenses expenses = expenseReportDAO.getMeals(employee.getID());
expenseTotal += expenses.getTotal();
} catch(MealExpensesNotFound e) {
expenseTotal += getMealPerDiem();
}
我们使用:
public class PerDiemMealExpenses implements MealExpenses {
public int getTotal() {
// return the per diem default
}
和
MealExpenses expenses = expenseReportDAO.getMeals(employee.getID());
expenseTotal += expenses.getTotal();
在swift中我们没有合并,所以我们可以跳过创建一个接口/协议并立即转到:
let expenses = expenseReportCalculator.getMeals(employee.id)
expenseTotal += expenses.getTotal() ?? getMealPerDiem
这是否意味着使用Swift时特殊情况模式是多余的?也许我要么忽略了这一点,要么在特殊情况下这种模式很有价值。
答案 0 :(得分:1)
我同意这个"特殊情况"讨论,在Martin的优秀 Clean Code的错误处理章节的定义正常流程部分,有点unswifty。
正如你所指出的那样,马丁的部分理由是切除对Java的重复使用"尴尬" (他的话,不是我的)try
- catch
模式,特别是如果你重复了很多。但是在Swift中,如果没有费用,你可能不会追求错误抛出模式,而只是返回一个可选项。而且,正如你所说,Swift nil
- 合并模式与try
- catch
模式相比更优雅。 (顺便说一下,Swift选项也会在该章的下两节中呈现无关紧要,不要返回空和不要通过空。)
罗伯特·马丁在本次讨论中称赞马丁福勒,但在 Refactoring中,福勒讨论了特殊情况"在上下文中模式null
检查Java的挑战以及所需的所有问题。但是,斯威夫特更优雅地处理选项,这让福勒的防守 - null
讨论很有用。
所以,我同意,MealExpenses
不是特殊情况的特别好的候选人"斯威夫特的模式。 (坦率地说,我不确定它是否是一般的优秀候选人,无论如何。)选项将是一个更自然的Swift解决方案。现在,如果我在整个地方使用相同的nil
合并模式乱丢我的代码,我会寻找避免重复它的方法,但我不一定会跳过介绍&# 34;特殊情况"仅用于此目的的模式。
值得注意的是,在 Refactoring中, Fowler提供了一个扩展的"特殊情况"例如,房东"客户"对于一些随机建筑可能是"没有客户" (例如,建筑物是空置的),一个未知的客户" (你知道有一个租户,但你不知道它是谁),或者是一个特定的客户。这个三元状态是我们必须开始思考超越简单的Swift可选项的状态。但是在那时我们可能会使用带有相关值的enum
,或者你可以想象使用"特殊情况"模式(但现在需要引入协议)。这取决于具体情况。尽管如此,我还没有遇到过我会倾向于添加"特殊案例"我的Swift代码中的模式。