分享

使用Axon框架开发CQRS应用

 CevenCheng 2011-01-07
Tutorial – Getting started with CQRS and Axon Framework « JTeam Blog / JTeam: Enterprise Java, Open

Axon是一个基于DDD领域驱动设计的搭建CQRS架构的框架,特点是可以和Spring整合。

Axon可以帮助简化建立基于EDA架构的CQRS应用,它对Domain Events的支持比较丰富,特别增强了Jdonframework没有的领域事件中的事务支持(不过个人觉得处理起来要复杂,因为事务本身就很棘手)。

Axon最大特点就是严格按照CQRS定义来编程,比如Command EventStore等等,好处是熟悉CQRS的人比较易懂,个人认为缺点是和DDD的统一语言要求有些距离了,如果只懂DDD,不懂CQRS的术语,还是不能方便使用Axon,这方面好像有些逻辑上疙瘩。个人观点。

开发步骤:
1.结合Maven建立项目Project,配置好需要的包。
2.建立Command类,如下:

public class CreateOrderCommand {

private final String orderId;
private final String productId;

public CreateOrderCommand(String orderId, String productId) {
this.orderId = orderId;
this.productId = productId;
}

public String getOrderId() {
return orderId;
}

public String getProductId() {
return productId;
}
}


建立Domain Events类,如下:

import org.axonframework.domain.DomainEvent;

public abstract class AbstractOrderEvent extends DomainEvent {
public String getOrderId() {
return getAggregateIdentifier().asString();
}
}

public class OrderCreatedEvent extends AbstractOrderEvent {

private final String productId;

public OrderCreatedEvent(String productId) {
this.productId = productId;
}

public String getProductId() {
return productId;
}
}

如果用Annotation注解来标明DomainEvent,也许更好(应该有),使用继承有些侵入性。

这些步骤之前,应该假设Order等领域模型已经建立好,上面这些类都应该属于行为操作性质,以前我们是写在Service中的。

3.建立CommandHandler,前面有事件发生,这里就有事件处理了,这里实际遵循事件模式中两个主题:触发者;接收者,CommandHandler属于接收者。关于CommandHandler讨论可见OOJDON的观点
接受Order订单的创建命令的处理者Handler代码如下,需要使用@CommandHandler标注:

@CommandHandler
public void createOrder(CreateOrderCommand command) {
orderRepository.add(new Order(command.getOrderId(), command.getProductId()));
}

@CommandHandler
public void confirmOrder(ConfirmOrderCommand command) {
Order order = orderRepository.load(new StringAggregateIdentifier(command.getOrderId()));
order.confirm();
}


在confirmOrder中,我们注意它委托了order.confirm(),让领域模型Order的方法confirm()确认自己的创建。

从这里看出,CommandHandler类似我们MVC中Controller,也就是控制器,专门接受来自界面的命令事件,类似Struts等中Action;JSF等中的界面Bean,或者类似Swing等中Listerner,或者类似SOA中的服务。当然在Jdonframework中,结合Struts 1.x的Handler可以节省不用写。

DCI架构中,Handler这里实际就是场景发生地,在简洁优雅上,DCI架构要比CQRS更简单,更倾向于业务统一语言,否则,只懂业务的领域专家还要学习设计模式中事件命令模式,将业务再翻译成事件语言,多一层翻译,就多一层信息失真,以前是将业务翻译成数据库语言,现在推翻了,就不能再多翻译这一层了。

前面谈到CommandHanlder再次触发Domain Model领域模型 Order中的方法,内容如下:

public void confirm() {
// we can only confirm an open order.
if (status == Status.OPEN) {
apply(new OrderConfirmedEvent());
}
}

@EventHandler
//Handler调用这里方法
private void onConfirm(OrderConfirmedEvent event) {
status = Status.CONFIRMED;
}


最后一步,编写查询Query组件:

@Component //Spring的标注
public class OrderEventHandler {

@EventHandler
public void handleOrderCreated(OrderCreatedEvent event) {
System.out.println(String.format(
"An order is created: [%s] for product: [%s]",
event.getOrderId(),
event.getProductId()));
}

@EventHandler
public void handleOrderCancelled(OrderCancelledEvent event) {
System.out.println(String.format(
"An order is cancelled: [%s]", event.getOrderId()));
}

@EventHandler
public void handleOrderConfirmed(OrderConfirmedEvent event) {
System.out.println(String.format(
"An order is confirmed: [%s]", event.getOrderId()));
}
}

看得出来,Axon可能没有对查询进行更多支持,JdonFramework提供查询缓存优化,自动分页查询等功能,将查询和命令之间数据共享通过缓存联系封装起来,更简化CQRS的查询和命令分离后的再结合。

从Axon和Jdonframework 6.0版本等CQRS框架看得出来,事件是一个解决领域驱动技术架构的好方法,但是如果事件比较多,都在空中飞来飞去,增加编程复杂性和代码可阅读性,这时,DCI架构,将模型带上角色帽子,拉到当前场景,让其演出,表演交互行为,就更加符合业务,符合DDD统一语言这个概念。







案例源码:
http://axonframework./files/axon_tutorial.zip

[该贴被banq于2011-01-05 10:02修改过]

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多