如何避免使用异常流控制? [英] How Can I Avoid Using Exceptions for Flow Control?

查看:272
本文介绍了如何避免使用异常流控制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  public CustomObject get(String key,Date ifModifiedSince)

基本上该方法应该返回 CustomObject 密钥相关联,当且仅当对象在 ifModifiedSince 之后被修改时。如果存储系统不包含,那么该方法应该返回null。



我的问题是这样的: / p>

如何处理密钥存在的场景,但对象已经修改

这很重要,因为使用这个类的一些应用程序将是Web服务和Web应用程序。这些应用程序将需要知道是否返回404(未找到)304(未修改)或200(OK,这里是数据)。



解决方案I 'm称重是:



  1. 存储系统不包含
    <$ c时,抛出一个自定义异常$ c> key


  2. ifModifiedSince 失败时抛出一个自定义异常。 li>
  3. 向CustomObject添加一个status属性。要求来电者检查财产。

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



尽管如此,我倾向于选项3。



有没有一个我不考虑的选项?有没有人对这三个选项有强烈的感觉?






对此问题的回答,释义: b>


  1. 提供一个包含
    方法,并要求调用者调用
    在调用 get(key,
    ifModifiedSince)
    之前,抛出
    异常,如果键不存在,
    返回null if对象没有被
    修改。

  2. 在复合对象中包含响应和数据(如果有)

  3. 使用预定义的常量来表示某些状态( UNMODIFIED,KEY_DOES_NOT_EXIST )。

  4. 实现接口为
    用作回调。

  5. 设计很好。






为什么我无法选择答案#1



我同意这是理想的解决方案,但是这是我已经(不情愿地)被解雇了。这种方法的问题是,在大多数使用这些类的情况下,后端存储系统将是第三方远程系统,如Amazon S3。这意味着包含方法将需要往返存储系统,这在大多数情况下应该是另一个往返。因为这个将花费时间和金钱,这不是一个选择。



如果不是这个限制,这将是最好的方法



(我意识到我没有提到这个问题的重要元素,但我正在努力保持简短,显然是相关的。)






结论:



在阅读了所有答案之后,我得出结论,在这种情况下,包装是最好的方法。本质上,我将模仿HTTP,包含元数据(头文件),包括响应代码和内容正文(message)。

解决方案

听起来你真的想要返回两个项目:响应代码和找到的对象。您可能会考虑创建一个轻松的包装器,并将其返回到一起。

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

然后,您可以创建一个保存您的响应代码和数据的新对。作为使用泛型的副作用,您可以再次使用这个包装器来实现您需要的任何对。



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


I have been assigned a project to develop a set of classes that act as an interface to a storage system. A requirement is that the class support a get method with the following signature:

public CustomObject get(String key, Date ifModifiedSince)

Basically the method is supposed to return the CustomObject associated with the key if and only if the object has been modified after ifModifiedSince. If the storage system does not contain the key then the method should return null.

My problem is this:

How do I handle the scenario where the key exists but the object has not been modified?

This is important because some applications that use this class will be web services and web applications. Those applications will need to know whether to return a 404 (not found), 304 (not modified), or 200 (OK, here's the data).

The solutions I'm weighing are:

  1. Throw a custom exception when the storage system does not contain the key
  2. Throw a custom exception when the ifModifiedSince fails.
  3. Add a status property to the CustomObject. Require caller to check property.

I'm not happy with any of these three options. I don't like options 1 and 2 because I don't like using exceptions for flow control. Neither do I like returning a value when my intent is to indicate that there was no value.

Nonetheless, I am leaning towards option 3.

Is there an option I'm not considering? Does anyone have strong feelings about any of these three options?


Answers to this Question, Paraphrased:

  1. Provide a contains method and require caller to call it before calling get(key, ifModifiedSince), throw exception if key does not exist, return null if object has not been modified.
  2. Wrap the response and data (if any) in a composite object.
  3. Use a predefined constant to denote some state (UNMODIFIED, KEY_DOES_NOT_EXIST).
  4. Caller implements interface to be used as callbacks.
  5. The design sucks.


Why I Cannot Choose Answer #1

I agree that this is the ideal solution, but it was one I have already (reluctantly) dismissed. The problem with this approach is that in a majority of the cases in which these classes will be used, the backend storage system will be a third party remote system, like Amazon S3. This means that a contains method would require a round trip to the storage system, which would in most cases be followed by another round trip. Because this would cost both time and money, it is not an option.

If not for that limitation, this would be the best approach.

(I realize I didn't mention this important element in the question, but I was trying to keep it brief. Obviously it was relevant.)


Conclusion:

After reading all of the answers I have come to the conclusion that a wrapper is the best approach in this case. Essentially I'll mimic HTTP, with meta data (headers) including a response code, and content body (message).

解决方案

It sounds like you actually want to return two items: the response code and the object found. You might consider creating a lightweight wrapper that holds both and return them together.

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

Then you can create a new Pair that holds your response code and the data. As a side effect to using generics, you can then reuse this wrapper for whatever pair you actually need.

Also, if the data hasn't expired, you could still return it, but give it a 303 code to let them know that it is unchanged. 4xx series would be paired with null.

这篇关于如何避免使用异常流控制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆