无声地失败的方法

时间:2015-07-02 08:18:17

标签: exception api-design

我有一个方法(或功能,或程序,这个问题并不重要)void DoStuff()。它取决于一些数据并具有副作用。此外,仅在某种状态下执行此操作才有效;在某些其他状态下,此操作无法执行。

现在,虽然我正在将其作为API开发,但我正在考虑实际使用此API的位置。执行此操作有两种典型情况:

  1. 如果状态有效,则应检查用户代码,如果不是,则实现自己的自定义逻辑。如果此代码最终试图在无效状态下实现此操作,则意味着它是程序员错误,应报告并进行调查。

  2. 在这种情况下,客户端实际上不需要做任何自定义逻辑,甚至不需要知道操作是否成功。

  3. 为了使我的API在这两种情况下都有用,我想公开这个方法的两个变体:一个DoStuff()将抛出异常 - 或者说,使用给定语言的能力来尽可能大地报告错误表示逻辑错误。而另一个,TryDoStuff(),根本不会做任何错误报告,并且会无声地失败。

    所以,我有两个问题:

    1. 创建两个API端点而不是一个端点听起来是个好主意吗?我认为这是一种方便,但通常情况下,更多API端点意味着需要支持更多代码和更复杂的API。

    2. 使用哪种合适的命名约定? TryDoStuff()是否有效?

    3. (这种语言与任何语言无关。我使用C#语法作为示例,但这个问题不是关于C#而是关于OOP,所以请不要添加这些标记。)

1 个答案:

答案 0 :(得分:1)

这可以通过多种方式解决:

  • 返回操作结果,丢失。
  • 失败时返回操作结果或默认值。
  • 失败时返回操作结果或错误指示。
  • 返回一个复杂的结果对象,其中一个状态可以表示失败。

现在,这些设计并不相互排斥;就像Parse / TryParse方法通常在.NET中成对出现一样,您可能希望提供每个方法的“安全保护”和大声失败的变体。更确切地说,以下三种处理方式似乎是可行的:

  • 如上所述,为每种方法提供两种变体。
  • 提供几个可以访问方法的API对象,一个“受保护的”对象和一个大声失败的对象。
  • 提供控制所有方法的一般行为的全局API模式设置。

现在,特别是选项2和3并不一定意味着要维护的全部代码量。在外部,您可以让所有API对象实现相同的通用接口。在内部,选项2和3(实际上也是选项1)将允许您只编写一次关键的内部方法,并根据实际调用的公共方法或当前的API模式来区别对待问题。 / p>

选择哪种设计(或设计组合)在很大程度上取决于各种背景因素:

  • 您的API的用户是什么用户;目标环境中的约定是什么?
  • API应该传达什么隐喻?例如,应该使用API​​“感觉”就像使用“设备”,或者像在轻量级服务模块上调用函数一样?