我被分配了一个项目来开发一组充当存储系统接口的类。要求是该类支持具有以下签名的 get 方法:
public CustomObject get(String key, Date ifModifiedSince)
基本上,该方法应该返回CustomObject
与key
if 关联的且仅当对象在 之后被修改时ifModifiedSince
。如果存储系统不包含,key
则该方法应返回 null。
我的问题是这样的:
如何处理密钥存在但对象未修改的情况?
这很重要,因为使用此类的一些应用程序将是 Web 服务和 Web 应用程序。这些应用程序需要知道是返回 404(未找到)、304(未修改)还是 200(好的,这是数据)。
我正在权衡的解决方案是:
- 当存储系统不包含
key
- 失败时抛出自定义异常
ifModifiedSince
。 - 将状态属性添加到 CustomObject。要求调用者检查属性。
我对这三个选项中的任何一个都不满意。我不喜欢选项 1 和 2,因为我不喜欢使用异常进行流控制。当我的意图是表明没有值时,我也不喜欢返回值。
尽管如此,我倾向于选项3。
有没有我不考虑的选项?有没有人对这三个选项中的任何一个有强烈的感觉?
这个问题的答案,意译:
- 提供一个
contains
方法并要求调用者在调用之前调用它get(key, ifModifiedSince)
,如果key不存在则抛出异常,如果object没有被修改则返回null。 - 将响应和数据(如果有)包装在复合对象中。
- 使用预定义的常量来表示某种状态 (
UNMODIFIED, KEY_DOES_NOT_EXIST
)。 - 调用者实现了用作回调的接口。
- 设计很烂。
为什么我不能选择答案#1
我同意这是理想的解决方案,但我已经(不情愿地)驳回了它。这种方法的问题在于,在使用这些类的大多数情况下,后端存储系统将是第三方远程系统,如 Amazon S3。这意味着一种contains
方法将需要到存储系统的往返行程,在大多数情况下,这之后会进行另一次往返行程。因为这会花费时间和金钱,所以这不是一种选择。
如果没有这种限制,这将是最好的方法。
(我意识到我没有在问题中提到这个重要元素,但我试图保持简短。显然它是相关的。)
结论:
在阅读了所有答案后,我得出结论,在这种情况下,包装器是最好的方法。本质上,我将模仿 HTTP,使用元数据(标头)包括响应代码和内容主体(消息)。