微服务下DDD的充血模式
之前分享过DDD,到底与微服务的关系如何?很多人还是觉得很虚幻,DDD那么复杂的理论,聚合根、值对象、事件溯源,到底我们该怎么入手呢?
实际上DDD和面向对象设计、设计模式等等理论有千丝万缕的联系,如果不熟悉OOA、OOD,DDD也是使用不好的。不过学习这些OO理论的时候,大家往往感觉到无用武之地,因为大部分的Java程序员开发生涯是从学习J2EE经典的分层理论开始的(Action、Service、Dao),在这种分层理论中,我们基本没有啥机会使用那些所谓的“行为型”的设计模式,这里的核心原因,就是J2EE经典分层的开发方式是“贫血模型”。 Martin Fowler在他的《企业应用架构模式》这本书中提出了两种开发方式“事务脚本”和“领域模型”,这两种开发分别对应了“贫血模型”和“充血模型”。 事务脚本开发模式
使用这种开发方式,对象只用于在各层之间传输数据用,这里的对象就是“贫血模型”,只有数据字段和Get/Set方法,没有逻辑在对象中。 我们以一个库存扣减的场景来举例:
设计一个Stock对象(Getter和Setter省略) public class Stock { private String spuId; private String skuId; private int stockNum; private int orderStockNum; }Service入口,设计一个StockService,在其中的lock方法中写逻辑,入参为(spuId,skuId,num) count = select stocknum from stock where spuId=xx and skuid=xx if count>num { update stock set stocknum=stocknum-num,orderstocknum=orderstocknum+num where skuId=xx and spuId=xx } else { //库存不足,扣减失败 } insert stock_log set xx=xx,date= new Date() ok,如果做的好一些,可以把update和select count合一,这样可以利用一条语句完成自旋,解决并发问题(高手)。 小节 有没有发现,在这个业务领域非常重要的核心逻辑 – 下订单扣减库存中操作过程中,
Stock对象根本不用出现,全部是数据库操作SQL,所谓的业务逻辑就是由多条SQL构成。Stock只是CRUD的数据对象而已,没逻辑可言。
领域模型的开发模式
这样做下单锁库存业务逻辑的时候,每次必须先从Repository根据主键load还原Inventory这个对象,然后执行对应的lock(num)方法改变这个Inventory对象的状态(属性也是状态的一种),然后再通过Repository的save方法把这个对象持久化到存储去。 领域模型开发方法最重要的是把扣减造成的状态变化的细节放到了Inventory对象执行,这就是对业务逻辑的封装。
领域模型和微服务的关系上面讲了领域模型的实现,但是他和微服务是什么关系呢?在实践中,这个Inventory是一个限界上下文的聚合根,我们可以认为一个聚合根就是一个微服务进程。 不过问题又来了,一个库存的Inventory一定和商品信息是有关联的,仅仅靠Inventory中的冗余那点商品ID是不够的,商品的上下架状态等等都是业务逻辑需要的,那不是又把商品Sku这样的重型对象引入了这个微服务?两个重型的对象在一个服务中?这样的微服务拆不开啊,还是必须依靠商品库?! 请参考下一篇,通过事件驱动架构来完成领域间的松耦合。(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Swift 常用方法总结
- Oracle SQL Developer工具常用配置
- 10款超实用Ajax和JavaScript开发框架
- HDU 1561 The more, The Better 依赖背包+树形DP
- c# – global.asax如果自定义错误打开,Application_Error事
- ruby-on-rails – PGError:错误:用于编码“UTF8”的无效字
- cocos2d-x俄罗斯方块--基于简单工厂的程序重构
- cocos2d-x getBoundingBox getContentSize getTextureRect
- dwr引发的血案之三hello world
- PostgreSQL删除除最旧记录之外的所有记录