代码之家  ›  专栏  ›  技术社区  ›  Declan McKenna

特殊情况模式在Swift中是否多余?

  •  1
  • Declan McKenna  · 技术社区  · 7 年前

    在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时,特殊情况模式是多余的?也许我没有抓住要点,或者在某些特殊情况下,这种模式会很有价值。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Rob Md Fahim Faez Abir    7 年前

    我同意这种“特殊情况”讨论 定义正常流量 第节 错误处理 马丁的卓越之章 Clean Code ,则, 有点不结实。

    正如您所指出的,Martin的部分理由是避免重复使用Java的“笨拙”(他的话,而不是我的话) try - catch 模式,尤其是如果你经常重复的话。但在Swift中,如果没有费用,您可能不会追求错误抛出模式,而只是返回可选的。正如你所说,还有Swift nil -凝聚模式与 尝试 - 接住 图案(顺便说一句,Swift optionals也将该章的下两部分视为无关紧要, 不返回Null 不传递Null .)

    罗伯特·马丁在这次讨论中赞扬了马丁·福勒,但在 Refactoring ,则, 福勒在以下背景下讨论了“特殊情况”模式 null 检查Java以及由此产生的所有问题。但斯威夫特处理期权的方式要优雅得多,这让福勒的防守更加出色- 无效的 讨论无意义。

    所以我同意 MealExpenses 不是Swift中“特殊情况”模式的特别好的候选者。(坦率地说,无论如何,我不确定总的来说这是一个很好的候选人。)Optionals将是一个更自然、更迅速的解决方案。现在,如果我在代码中乱扔相同的 将模式整合到所有地方,我会寻找避免重复的方法,但我不一定会为了这个目的而直接引入“特殊情况”模式。

    值得注意的是 重构 ,则, 福勒提供了一个扩展的“特例”示例,其中某栋随机建筑的房东“客户”可能是“无客户”(例如,该建筑是空的)、“未知客户”(你知道有租户,但你不知道是谁)或特定客户。这个三元状态是一个我们必须开始思考超越简单的Swift选项的状态。但在这一点上,我们可以使用 enum 也可以使用“特殊情况”模式(但现在需要引入协议)。这取决于具体情况。尽管如此,我还没有遇到过我倾向于在Swift代码中添加“特殊情况”模式的情况。