我们的应用程序中的一个要求是对所有内容实施“双重控制”,包括CRUD操作。 需要明确的是,“双重控制”是一项功能,需要更改数据才能由变更请求者以外的其他人批准。因此,当用户对数据进行更改时,它不会直接提交到生产表。我知道有几种方法可以实现这一点(例如登台表),但其他时间也是如此。
问题,有这样的要求,你认为我们应该遵循生成的Roo + GWT(使用RequestFactory)的标准“以数据为中心”的方式吗?
或者我们最好实施我们自己的“命令模式”框架来支持双重控制?
我倾向于后者。我的直觉(基于Roo + GWT的3天游戏)说,RequestFactory的设计并没有考虑到双重控制,如果我们试图强行进入,我们就会碰壁。我会非常乐意在这里被证明是错误的。
答案 0 :(得分:4)
你看过RequestFactory的ServiceLayerDecorator
了吗?它调解有效负载处理与域对象和代码之间的所有交互。例如,您可以覆盖getProperty
和setProperty
方法来读取和写入某种包含待定突变的“影子”日志。
如果需要为对象,方法或属性实现ACL,可以使用loadDomainObject
和resolveX
方法来控制任何给定请求可以与之交互的服务器端类。
要在自定义装饰器中连接,您可以继承RequestFactoryServlet
并调用two-arg构造函数。或者,您可以使用从ServiceLayer.create()
返回的对象实例化SimpleRequestProcessor
。
实施说明:所有RequestFactory的默认域互动行为都是使用一系列ServiceLayerDecorators
构建的;如果要查看用于构建ServiceLayerDecorator
的示例代码,请查看GWT源代码。需要注意的一点是,如果您的装饰者调用ServiceLayer
API中定义的任何方法,它应该使用getTop()
提供的实例。 ServiceLayerDecorator
个实例应该是无状态且可重复使用的,因此如果您需要跨方法调用维护状态,请考虑使用ThreadLocal
变量,类似于RequestFactoryServlet.getThreadLocalX()
。
答案 1 :(得分:3)
这取决于您想要的“用户体验”,特别是您是否希望用户验证已更改内容的“差异”,或批准“新版本”(快照)。
如果你想要差异,因为RequestFactory只向服务器发送差异(即实际更改用户,或者你对代码做出的代码),然后根据Bob的建议拦截setProperty
次呼叫肯定是一种方式要做到这一点(使Bob的建议更加清晰:你将差异“存储”在静态ThreadLocal
中,这样你就可以从服务调用中检索它了。您还可以使用“更智能”的域对象,在调用setter时构建内部差异;然后,对象本身的每个对象都可以访问diff。
如果你想要快照,那么你只需要实现你的服务来将修改后的对象存储在“临时表”或其他任何内容中,而不是存储在“生产表”中;然后在调用“批准”服务时将它们“移动”到“生产表”。
有一件事(对我来说)很明显,你必须围绕“双重控制”建模你的服务和/或对象,而不是试图在“简单的CRUD”操作中做到这一点(即“保存”不是“保存”,这是“发送批准”;并且有一个单独的“批准”操作。)