当前位置: 首页 > 面试题库 >

如何避免使用异常进行流控制?

阎雪峰
2023-03-14
问题内容

我被分配了一个项目来开发一组用作存储系统接口的类。要求是该类支持具有以下签名的get方法:

public CustomObject get(String key, Date ifModifiedSince)

基本上,该方法应该返回CustomObjectkeyif和仅在after之后被修改的对象相关联ifModifiedSince。如果存储系统不包含,key则该方法应返回null。

我的问题是这样的:

如何处理场景的关键存在,但对象已经 被修改?

这很重要,因为使用此类的某些应用程序将是Web服务和Web应用程序。这些应用程序将需要知道是返回404(未找到),304(未修改)还是200(确定,这是数据)。

我正在权衡的解决方案是:

  1. 当存储系统不包含自定义异常时,将引发自定义异常 key
  2. ifModifiedSince失败时引发自定义异常 。
  3. 将状态属性添加到CustomObject。要求调用者检查属性。

我对这三个选项都不满意。我不喜欢选项1和2,因为我不喜欢将异常用于流控制。当我的意图是表明 没有值 时,我也不喜欢返回

但是,我倾向于选择3。

我有没有考虑的选项?是否有人对这三种选择有强烈的感情?

对此问题的答案解释为:

  1. 提供一种contains 方法,要求调用者在调用之前调用它get(key, ifModifiedSince),如果键不存在,则引发异常;如果未修改对象,则返回null。
  2. 将响应和数据(如果有)包装在复合对象中。
  3. 使用预定义的常量表示某种状态(UNMODIFIED, KEY_DOES_NOT_EXIST)。
  4. 调用者实现接口以用作回调。
  5. 设计很烂。

为什么我不能选择答案#1

我同意这是理想的解决方案,但这是我已经(勉强)驳回的解决方案。这种方法的问题在于,在大多数情况下,使用这些类时,后端存储系统将是第三方远程系统,例如Amazon
S3。这意味着一种contains方法将需要往返存储系统,在大多数情况下,将需要进行另一次往返。因为这 将花费时间和金钱 ,所以这不是一个选择。

如果不是因为这种限制,那将是最好的方法。

(我意识到我没有在问题中提到这个重要因素,但我试图将其保持简短。很显然,这是相关的。)

结论:

阅读所有答案后,我得出的结论是,在这种情况下,包装器是最好的方法。本质上,我将模仿HTTP,并使用元数据(标头)包括响应代码和内容主体(消息)。


问题答案:

听起来您实际上想返回两个项目:响应代码和找到的对象。您可能会考虑创建一个轻量级的包装器,将两个包装器放在一起并将它们放回一起。

public class Pair<K,V>{
  public K first;
  public V second;
}

然后,您可以创建一个新的对,其中包含您的响应代码和数据。作为使用泛型的副作用,然后可以将此包装器重新用于实际需要的任何对。

另外,如果数据还没有过期,您仍然可以返回它,但是给它一个303代码让他们知道它是不变的。4xx系列将与配对null



 类似资料:
  • 我有zuul网关服务器,没有eureka服务发现。 我使用下面显示的yml文件连接微服务和zuul。 当我执行URL超时时,会发生异常

  • 问题内容: 我有这样的代码: 实例化B可以按预期工作,但是实例化C无限递归并导致堆栈溢出。我该如何解决? 问题答案: 实例化C调用时,仍然是C,因此super()调用将其带回B。 调用super()时,请直接使用类名。因此,在B中,请致电,而不是(最好在C中使用)。在Python 3中,您可以仅使用不带参数的super()来实现同一目的

  • 我正在尝试正确地使用ByteBuffer和BigEndian字节顺序格式。。 我有几个字段,我试图把它存储在Cassandra数据库之前放在一个单一的ByteBuffer中。 我将要写入Cassandra的字节数组由三个字节数组组成,如下所述- 现在,我需要快速压缩attributeValue数据,然后再将其存储在Cassandra中- 现在,我将编写,和snappy压缩的一起组成一个单字节数组,

  • 我有以下方法: 它在内部调用: 第二个方法有一个try/catch persistenceException。问题是事务回滚,然后到达PersistenceException。 编辑4-更多信息: 1)从apply中删除@transactional,将@transaction仅保留在此异常的applyLog结果上: javax.persistence.persistenceException:or

  • 我有没有eureka服务发现的zuul网关服务器。 我使用如下所示的yml文件连接微服务和zuul。

  • 我试图比较两个不同对象的名称,但是当使用方法将一个项目与null进行比较时,我一直得到异常。我尝试了很多方法,包括other.equals(哈哈)、haha.equals(其他)等等,但都失败了。