当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何避免使用异常进行流量控制?》经验,为你挑选了2个好方法。

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

public CustomObject get(String key, Date ifModifiedSince)

基本上该方法应该返回CustomObjectkeyif 关联的,并且只有在对象被修改之后才会返回ifModifiedSince.如果存储系统不包含,key则该方法应返回null.

我的问题是:

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

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

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

    当存储系统不包含时,抛出自定义异常 key

    ifModifiedSince失败时抛出自定义异常 .

    将状态属性添加到CustomObject.要求来电者查看房产.

我对这三个选项中的任何一个都不满意.我不喜欢选项1和2,因为我不喜欢使用流控制的异常.当我的目的是表明没有价值时,我也不喜欢返回.

尽管如此,我倾向于选择3.

有没有我不考虑的选择?有没有人对这三种选择中的任何一种都有强烈的感受?


这个问题的答案,转述:

    提供一个contains 方法并要求调用者在调用之前调用它get(key, ifModifiedSince),如果key不存在则抛出异常,如果没有修改object则返回null.

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

    使用预定义常量表示某个state(UNMODIFIED, KEY_DOES_NOT_EXIST).

    调用者实现了用作回调的接口.

    设计很糟糕.


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

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

如果没有这个限制,这将是最好的方法.

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


结论:

在阅读完所有答案之后,我得出的结论是,在这种情况下,包装器是最好的方法.基本上我会模仿HTTP,包括响应代码和内容正文(消息)的元数据(标题).



1> James..:

听起来你实际上想要返回两个项目:响应代码和找到的对象.您可以考虑创建一个包含两者并将它们一起返回的轻量级包装器.

public class Pair{
  public K first;
  public V second;
}

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

此外,如果数据尚未过期,您仍然可以返回它,但是给它一个303代码,让他们知道它没有变化.4xx系列将配对null.


措辞选择不当.是的,它是强类型的,但"配对"是模糊的.对什么?是的你指定"Pair ",但Integer是什么意思?这是通用的,然后令人困惑.希望至少在那时,代码是在包装器中输入的.

2> OscarRyz..:

根据给定的要求,您无法执行此操作.

如果您设计了合同,则添加条件并调用调用者

exists(key): bool

服务实现如下所示:

if (exists(key)) {
    CustomObject o = get(key, ifModifiedSince);
    if (o == null) { 
      setResponseCode(302);
    } else {
      setResponseCode(200);
      push(o);
   }

} else {
      setResponseCode(400);
}

客户端保持不变,从未注意到您已经预先验证过.

如果你没有设计合同可能有一个很好的理由,或者可能只是设计师(或建筑师)的错误.但既然你无法改变它,那么你也不必担心.

那么你应该遵守规范并继续这样:

 CustomObject o = get(key, ifModifiedSince);

 if (o != null) {
     setResponseCode(200);
     push(o);
  } else {
     setResponseCode(404); // either not found or not modified.
  }

好的,在这种情况下你不会发送302,但可能就是它的设计方式.

我的意思是,出于安全原因,服务器不应该返回更多信息[探测器获取(键,日期)只返回null或object]

所以不要担心.与您的经理交谈,让他知道这个决定.用这个决定评论代码.如果你有建筑师在手,确认这个奇怪的限制背后的理由.

你可能没有看到这一点,他们可以根据你的建议修改合同.

有时候,如果想要正确行事,我们可能会出错并损害我们应用的安全性.

与您的团队沟通.

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有