提问人:Christophe Herreman 提问时间:10/7/2008 最后编辑:David HallChristophe Herreman 更新时间:11/29/2008 访问量:3439
DDD 和异步存储库
DDD and Asynchronous Repositories
问:
我们正在开发一个富客户端(用 Flex 编写),它使用 RMI 和 JMS 连接到 Java 后端。我正在考虑以 DDD 方式实现客户端,以便它具有用于域对象上的 CRUD 操作的存储库。
然而,问题在于所有后端通信都是异步进行的,我无法强制客户端等待继续,直到它收到响应。这意味着,在低级别上,我可以在远程对象上调用方法,并获取 AsyncToken 作为返回值。然后,我可以侦听 asynctoken 上的事件,以查看调用是通过还是失败。然而,这打破了存储库背后的主要思想,即向客户隐藏技术细节。
我猜可能有 2 个选项:
- 让存储库上的方法返回 AsyncToken,这对我来说似乎是一个混乱的解决方案
- 让方法返回一个空集合(例如,对于 findAll),该集合将在收到响应时被填充。
两者都有利有弊,我想从你们那里得到一些意见。
(更进一步,什么是好的缓存策略?根据具体情况,我不希望存储库每次从服务器请求所有实体时都调用服务器。这将如何影响存储库上方法的签名。
答:
一个分支是在存储库前面创建一个立面。客户端将对 Facade 进行异步调用,而 Facade 又会对存储库进行同步调用。这将允许您的存储库继续以同步方式工作,而 Facade 管理调用的异步方面。
我建议返回一个 AsyncToken,因为返回一个空集合感觉不对。
如果要从缓存返回数据,请返回一个 CompletedAsyncToken (: AsyncToken),每当订阅 COMPLETE 事件(然后删除处理程序)时,该令牌都会自动触发包含数据的 COMPLETE 事件。
public class CompleteAsyncToken : AsyncToken
{
public function CompleteAsyncToken(data : Object)
{
super(data);
}
public override addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false) : void
{
super.addEventListener(type, listener, useCapture, priority, useWeakReference);
if (type == Event.COMPLETE)
{
// Don't just execute listener as EventDispatcher is not that simple
super.dispatchCompleteEvent();
super.removeEventListener(type, listener);
}
}
评论
addResponder(responder:IResponder)
responder.result(some empty result object)
Flex 和 Flash Remoting 本质上是异步的,因此与这种范式作斗争会给您带来很多麻烦。我们的服务委托从每个方法返回 AsyncToken,我们从来没有遇到过问题。
如果要确保应用程序在结果/错误返回之前不会呈现新视图或执行其他逻辑,可以执行以下操作:
- 为将调用“发布结果/故障代码”的自定义事件附加事件侦听器
- 进行异步调用
- 处理结果/故障
- 调度自定义事件以从 #1 触发侦听器
请记住,每次进行异步调用时,这都会导致大量烦人的沸腾板代码。我会非常仔细地考虑您是否真的需要同步执行路径。
评论