【问题标题】:Batch and business layer communication批处理和业务层通信
【发布时间】:2012-04-19 13:15:29
【问题描述】:
我正在使用 Spring 批处理设计一个批处理应用程序,其中我具有以下架构(层):
- 我放置所有spring批处理代码(读取文件,处理和写入)的顶级模块。这个顶级模块特定于文件的某种格式。所以,我将来可能会有一个新的并行模块,能够读取/处理/写入新格式。与格式无关,文件的每一行对应于要执行的特定操作。例如,每一行可以表示“将行项目 X 添加到订单 Y”的操作。因此,对于每一行,在完成读取和处理后,我使用一个自定义的 ItemWriter 来调用紧接其下层的所需操作。
- 实现不同批处理操作的业务逻辑层。这些操作中的每一个都是使用域层对象实现的。例如,“添加订单项;X 到订单 Y”操作将通过使用 OrderRepository 检索订单然后调用订单的 addLineItem 方法来实现。
- 我拥有所有域对象的域层。按照前面的示例,我有 Order 和 LineItem 实体。
我的问题是:
- 是否有最佳实践(可能是特定的设计模式)用于顶层模块和业务逻辑层之间的接口?
- 假设每个文件只包含一个订单的行。编写每一行的幼稚方法是每行调用一个批处理操作。在这种情况下,对于每一行,都会调用 OrderRepository 以检索订单,然后保存订单。我正在考虑另一种按块编写行的方法(就像我们使用 Spring 批处理一样)。写操作采用的参数类型为 List。按照第二种方法,我需要向业务操作传递将块添加到相关订单所需的数据。使用哪种形式在顶层模块和业务逻辑层之间传递信息?
谢谢
【问题讨论】:
标签:
design-patterns
domain-driven-design
spring-batch
【解决方案1】:
是否有最佳实践(可能是特定的设计模式)可用于
顶层模块与业务逻辑层的接口?
afaik 没有真正的最佳实践,与已知的最佳实践不同,但批次通常需要解决性能要求/约束,甚至更经常产生性能问题,所以我的最佳实践是:
- 考虑数据和数据流
- 有多少数据?
- 瓶颈是什么? (处理与写作,通常是写作部分)
给你一些编写器和业务层接口的灵感
- 使用ItemWriterAdapter,它可以使用businessLayer.addOrderItem 方法
- 编写自己的包装器
- 将业务层移到编写器中,很少真正需要重用批量优化业务层
我会选择选项 2,因为在批处理上下文中我想使用列表和批处理 SQL
像往常一样,这取决于您的具体要求:-)
ItemWriter 包装器示例
public class SimpleItemWriter implements ItemWriter<SimpleItem> {
@Override
public void write(List<? extends SimpleItem> items) throws Exception {
// do something, e.g. delegate to another spring bean
}
}
ItemWriterAdapter 配置示例
<bean id="sample-item-writer-adapter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
<property name="targetObject" ref="businessLayerBean" />
<property name="targetMethod" value="doSomething"
</bean>
<step id="splitFilesStep">
<tasklet>
<chunk
reader="itemReader"
writer="sample-item-writer-adapter"
commit-interval="5">
</chunk>
</tasklet>
</step>