Java 当调用调用代理以聚合来自多个端点的数据的方法时,我可以使用什么模式来部分成功?
例如,假设我有以下类:Java 当调用调用代理以聚合来自多个端点的数据的方法时,我可以使用什么模式来部分成功?,java,design-patterns,partial,aggregator,Java,Design Patterns,Partial,Aggregator,例如,假设我有以下类: public class FruitBasket { private List<Apple> apples; private List<Orange> oranges; // getters and setters... } 现在进一步假设getFruitBasket方法聚合了来自两个不同来源的数据,这些数据通过代理访问。例如,有一个服务器AppleTree获取类型为Apple的对象,还有一个服务器OrangeTree获取
public class FruitBasket {
private List<Apple> apples;
private List<Orange> oranges;
// getters and setters...
}
现在进一步假设getFruitBasket
方法聚合了来自两个不同来源的数据,这些数据通过代理访问。例如,有一个服务器AppleTree
获取类型为Apple
的对象,还有一个服务器OrangeTree
获取类型为Orange
的对象,这两个服务器都通过名为OrchardGate
的代理进行访问。这就是为什么我想编写一个getFroothBasket
方法,而不是getApple
和getOranges
,以最小化从应用程序调用果园门时的延迟
如果成功检索到Apple
对象和Orange
对象,则没有问题,我只需返回果篮
。如果访问OrchardGate
或在AppleTree
和OrangeTree
中出现问题,我也可以通过抛出RuntimeException
的后代来处理此问题(甚至是Exception
,如果我将其添加到getFruitBasket
throws
子句中(视情况而定)
但是,在部分成功的情况下会发生什么?如果我可以很好地访问AppleTree
服务器,但由于OrchardGate
和OrangeTree
之间的某些传输问题而无法访问OrangeTree
服务器,会发生什么
据我所知,只有四种选择,而且都非常可怕:
- 我可以抛出一个异常,这意味着即使成功接收了
Apple
对象,由于缺少Orange
对象,水果篮也不会返回
- 我可以忽略该错误,只返回一个
Orange
对象的空列表。这意味着客户端在查找Orange
对象时将看不到错误,相反,它看起来就像OrangeTree
服务器上不存在Orange
对象一样
- 我可以在
果篮
中添加一个名为errorCodes
的字段,其中包含访问果篮
时遇到的错误列表。然后,我可以在名为路径
的列表中添加一个错误代码,以表示我遇到的错误。但是,此字段errorCodes
不可用在果篮
域对象上的长度很长。此字段与果篮
无关,但仅在用于检索果篮
的事务中相关
- 我可以抛出一个异常,但是将不完整的
果篮
附加到异常。这也很可怕,因为异常应该只包含错误信息-它们不应该包含任何果篮
我已经用Java描述了这个问题,但我想这个问题会扩展到多种语言。我很惊讶还没有找到关于这个问题的讨论。是否有任何标准的编写方法模式可以获得部分成功?或者我错过了什么?我认为这种方法没有任何错误
我可以向水果篮添加一个名为errorCodes的字段,该字段包含访问水果篮时遇到的错误列表。然后我可以向该列表添加一个名为PATH_FLOODED的错误代码,以表示我遇到的错误。但是,该字段errorCodes根本不属于水果篮域对象。此字段不重新命名levant指向一个果篮,但仅在事务中检索果篮
FruitBasketTransaction{
果篮果篮;
列出错误代码;
//…构造函数和getter
}
公共水果篮事务处理GetFruitball(){
// ...
}
//在你的申请表中的某个地方
FroothBasketTransaction=GetFroothBasketTransaction();
如果包含(transaction.errorCodes、APPLE_错误){
//…告诉用户
}
如果包含(transaction.errorCodes,橙色错误){
//…告诉用户
}
giveFruitToUser(transaction.getFruitBasket());
A部分结果,时间快照。对于收集各种在线词典和服务的翻译系统也是如此,这些词典和服务可能不可用,也可能不可用。通常使用控件“进一步搜索/中止”
一般来说,在您提供结果时有一个最小的阈值,例如一个代理提供其贡献的结果
模式不是结果,而是管理正在进行的搜索任务,提供结果。还需要进行一些更改管理。当使用部分结果制作果篮时,稍后,您可能希望重复制作果篮,并提供更多变化
服务
提供提供数据包[]
的时间线:
`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}
使用哪一种隐喻取决于一点:例如,项目管理,或者在您的生产案例中。我认为您需要一种可能称为
loadFrootBasket()
从服务器加载Apple和Orange对象。由于必须访问服务器才能获取苹果和Orange,因此可以在访问成功时将boolean
设置为true
,在访问失败时将false
设置为we。然后在使用GetFrootBasket之前()
您可以询问加载果篮的类,如果它hasApples()
或hasaoranges())
。这样你就不必多次访问服务器,也可以显示不同的错误。为什么不使用类似水果的抽象类
,并在水果篮中使用列出水果
。然后创建苹果类
和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());
`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}