在调用调用代理以聚合来自多个端点的数据的方法时,我可以使用什么模式来部分成功?

What pattern can I use for partial success when calling a method which calls a proxy to aggregate data from multiple endpoints?

举个例子,假设我有以下 class:

public class FruitBasket {
    private List<Apple> apples;
    private List<Orange> oranges;
    // getters and setters...
}

现在假设我在某个地方也有一个获取 FruitBasket.

的方法
public FruitBasket getFruitBasket() {
    //...
}

现在进一步假设 getFruitBasket 方法聚合来自两个不同来源的数据,这些数据通过代理访问。例如,服务器 AppleTree 获取类型 Apple 的对象,服务器 OrangeTree 获取类型 Orange 的对象,两者都通过名为OrchardGate。这就是为什么我想编写一个 getFruitBasket 方法而不是 getApplesgetOranges 的原因,以最大限度地减少从我的应用程序调用 OrchardGate.[= 时的延迟53=]

Apple个对象和Orange个对象检索成功的情况下,没有问题,我可以return FruitBasket。如果访问 OrchardGate 或在 OrchardGate 内部出现问题,或者在 AppleTreeOrangeTree 中出现问题,我也可以通过抛出 RuntimeException 的后代来处理这个问题(甚至 Exception,如果我适当地将其添加到 getFruitBasket throws 子句中)。

然而,在部分成功案例中会发生什么?如果我可以正常访问 AppleTree 服务器,但由于 OrchardGateOrangeTree 之间的某些传输问题而无法访问 OrangeTree 服务器,会发生什么情况?

据我所知只有四个选项,而且都非常糟糕:

我在 Java 中描述了这个问题,但我想这个问题会扩展到多种语言。我很惊讶没有找到关于它的讨论。是否有任何标准模式可以 return 部分成功地编写方法?或者我错过了什么?

我认为这种方法没有任何问题。

I could add a field to FruitBasket called errorCodes which contained a list of the errors encountered when accessing the FruitBasket. Then I could add an error code to that list called PATH_FLOODED to signify the error I had encountered. However, this field errorCodes does not belong on the FruitBasket domain object at all. This field is not relevant to a FruitBasket, but only in the transaction to retrieve the FruitBasket

FruitBasketTransaction {
  FruitBasket fruitBasket;
  List<Error> errorCodes;

  // ... constructor and getters
}

public FruitBasketTransaction getFruitBasket() {
  // ...
}

// In your application somewhere
FruitBasketTransaction transaction = getFruitBasketTransaction();
if contains(transaction.errorCodes, APPLE_ERROR) {
  // ... tell the user
}
if contains(transaction.errorCodes, ORANGE_ERROR) {
  // ... tell the user
}

giveFruitToUser(transaction.getFruitBasket());

部分结果,时间快照。这同样适用于收集各种在线词典和服务的翻译系统,这些词典和服务可能可用也可能不可用。一般用控件 "search further/abort."

一般来说,在您提供结果的地方有一个最小阈值,比如一个代理提供其贡献的结果。

模式 不是结果模式,而是管理正在进行的搜索任务,提供结果。也应该进行一些变更管理。当使用部分结果制作水果篮时,稍后您可能想要重复制作更多变化的水果篮。

A service 提供时间线提供 data packages[]:

`Service A:   (start) [pack 0] (t1) [pack 1] (t2) [pack 2] (t3) {running}
`Service B:   (start) (t1) [pack 3] (t2) (t3) [pack 4] (t4) {ended}

使用哪个比喻取决于一点:例如项目管理,或者在您的案例中是生产。

我想你需要另一种方法 loadFruitBasket() 从服务器加载 Apple 和 Orange 对象。因为你必须访问服务器才能获得苹果和橘子,所以你可以在访问成功时将boolean设置为true,或者在访问失败时设置为false。然后在使用 getFruitBasket() 之前,您可以询问加载 FruitBasket 的 Class 是 hasApples() 还是 hasOranges() 。有了这个你就不必多次访问服务器并且可以显示不同的错误。