我已被分配了一个项目,以开发一套课程,作为一个接口,以存储系统。一个要求是,这类支持一个得到的方法与以下特征:

public CustomObject get(String key, Date ifModifiedSince)

基本方法是应该返回 CustomObject 关联 key 如果且只有如果对象已被修改之后 ifModifiedSince.如果存储系统不包含 key 然后,该方法应该返回null。

我的问题是这个:

我怎么处理这种情况的关键存在,但是对象 经修改的?

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

解决办法,我称是:

  1. 扔一个自定义的异常时 储存系统没有包含 key
  2. 扔一个自定义的异常时 ifModifiedSince 失败。
  3. 增加一个状态的财CustomObject.要求呼叫者检查的财产。

我不乐意与任何这三个选项。我不喜欢选择1和选择2因为我不喜欢使用的异常流量控制。我也不喜欢返回值时,我的意图是要表明,没有 没有价值.

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

有一个选项我没考虑吗?没有任何人有强烈的感情有关的任何这三个选择?


对这个问题的答案,解释:

  1. 提供一个 contains 方法和要求呼叫者叫它 之前的呼叫 get(key, ifModifiedSince), 扔 异常,如果关键不存在, return null,如果对象没有 修改。
  2. 包裹的响应和数据(如果有的话) 在一个复合的对象。
  3. 使用一个预先定义的不断来表示一些国家(UNMODIFIED, KEY_DOES_NOT_EXIST).
  4. 呼叫者实现接口 作为回调。
  5. 设计糟透了。

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

我同意,这是理想的解决方案,但它是一个我已经(无奈地)驳回。这种方法的问题是,在大多数情况下,这些课程将使用后端存储系统将是一个第三方远程系统,如亚马逊S3。这意味着一个 contains 方法将需要往返于储存系统,该系统在大多数情况下将会随后通过另一轮的旅行。因为这个 将花费时间和金钱, 它不是一个选项。

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

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


结论:

后读取所有的答案,我们得出的结论是,一个包装是最好的办法在这种情况。基本上我就模仿HTTP,用元数据(标题)包括一个响应的代码和内容体(消息)。

有帮助吗?

解决方案

这听起来像你真的想要返回的两个项目:响应的代码和目的发现。你可以考虑创建一个轻型包装,保持两者并返回他们在一起。

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

然后您可以创建一个新的对于拥有你的回应代码和数据。作为一个副作用使用仿制药,然后你可以重复使用这个包装为什么对你的实际需要。

此外,如果数据没有到期,你仍然可以返回,但给它一个303码要让他们知道,这是不变的。4xx系列会搭配 null.

其他提示

有鉴于要求你不能这样做。

如果是你设计的合同, 然后添加一个条件,并使该叫调用

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.
  }

Ok,你不是送302在这种情况下,但也许这就是它的方式设计。

我的意思是,出于安全原因,服务器不应返回的更多信息,比, [探测是得到(键,日期)才回null或对象]

所以不要担心它。谈谈你的经理,并让他知道这一决定。评论的代码这一决定。如果你有建筑师在一方面确认背后的理由这个奇怪的限制。

机会是他们你没有看到这来了,他们可以修改合同之后,你建议。

有时候,同时要继续执行正确的,我们可以继续进行错误和妥协的安全的我们的应用程序。

与你的团队。

你可以创建一个特殊的最终CustomObject作为一个"标记",以表明不变:

static public final CustomObject UNCHANGED=new CustomObject();

和测试用于一个匹配"=="代替。等().

它还可能作为回null上不变,并把一个异常上不存在?如果我必须选择你的3个,我会选择1,因为这似乎是最特殊的情况。

寻找一个对象不存在似乎是一个特殊的情况下给我。耦合的方法,允许一个呼叫者来确定,如果对象是存在的,我认为这将是确定以扔的例外时,它不。

public bool exists( String key ) { ... }

呼叫者可以这样做:

if (exists(key)) {
   CustomObject modified = get(key,DateTime.Today.AddDays(-1));
   if (modified != null) { ... }
}

or

try {
    CustomObject modified = get(key,DateTime.Today.AddDays(-1));
}
catch (NotFoundException) { ... }

该问题与例外情况是他们都是信号的一个"快速失败"的情况(即如果不处理,一个例外 停止 应用程序)由于一个特殊的 和异常 行为。

我不认为"该方案的关键存在,但是目的未经修改"是一个例外,当然不是一个异常之一。

因此,我将不使用例外,而是我会文件的行动的呼叫者的需要做,以便正确地解释本结果(财产或特殊对象)。

如何严格的要求,方法的签名吗?

它看起来好像你正在一个项目,该项目仍在进行中。如果消费者的类是其他开发的,你可以说服他们的方法,签署他们已要求是不够?也许他们还没有意识到,应该有两个独特的故障模式(项不存在和对象未经修改)。

我将讨论它,与你的主管,如果这是一个选项。

我还是返回null。

打算在财产是返回的对象,这是修改后的指定的日期。如果返回null为对象不是确定的,那么肯定回null为未经修改的目的是确定。

我个人将返回的null非修改的对象,并把一个异常用于非现有的对象。这似乎更加自然。

你说的很对不使用例外流量控制顺便说一句,所以如果你只有3个选择,你的直觉是正确的。

你可以遵循。净库模式并有一个公共静只读场中的定义称为对象 CustomObject.空 的类型 CustomObject (像串。空和Guid。空)。你可以返回这个如果目的不是修改(功能的消费者将需要比较)。
编辑: 我只是刚刚发现你的工作,但原则上仍然适用

这让你有选择的以下

  • Return null if的关键并不存在。

  • 返回 CustomObject.空 如果关键的存在,但是对象尚未被修改。

其缺点是,消费者需要知道之间的差空返回值和CustomObject.空返回值。

也许是酒店会更恰当地称为 CustomObject.NotModified 作为空是真正用于的价值类,因为他们不能为空。还 NotModified 会传达的意义的领域更容易地到消费者。

在(目的)的接口有关的要求,严重破坏。你尝试去做不相关的事情一方法。这是走向软件的地狱。

提供回调作为参数,其中的回流可能是事件驱动的,或器驱动的。

你有你的类的接口定义的各种可能发生的错误的,通过在CustomObject作的参数为事件,如果需要的话。

public interface Callback {
  public void keyDoesNotExist();
  public void notModified(CustomObject c);
  public void isNewlyModified(CustomObject c);
  .
  .
  .
}

在这种方式,允许实施者的回调界定什么时候做的事件发生,而且你可以选择通过该接口,否,条件要求传递的检索到的对象。最后,它可降低复杂性的逻辑上的回报。您的方法不止一次。实现API不需要这样做,因为它的完成。

如果它是可以接受的,你可以回放大CustomObject(a wrapper),其中载有价值所表示的对象及其修改国家,如果有的话,等等。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top