DDD 领域驱动实践
- 业务初期由于业务简单 只要简单的crud就可以满足。这个时候系统功能是清晰的。但是随着疯狂的迭代 不断的业务演化。业务逻辑越来越复杂。系统也越来越冗余。模块彼此关联。资深业务开发也很难说清楚这一块会涉及到什么功能。
- 这个时候要基于这个版本去做迭代 需要花费大量的时间去做回溯。更加不要提如果更新带来的不可预知的影响面。
- 如果PM没有考虑这个点 开发去开发的时候 会+额外大量的工作量。
订单服务提供了查询 创建订单等订单核心功能。也提供了订单评价、支付、保险的入口。然后我们的表也是个订单大表,包含了非常多的字段。在我们维护代码时,改动一个地方就会导致一些莫名的问题。很可能就是想改动评价 但是却影响到了下单。虽然可以通过测试保证功能 这样带来的问题就是 测试工作量加大 + 开发并行的时候 改动重叠 从而恶性循环。
有一种解决方案
按照演进式设计理论。让系统的设计随着系统实现的增长而增长。不需要提前做设计,让系统随着业务成长而演进。敏捷实战中的重构 TDD以及持续集成可以对付各种混乱问题。
- 重构-保持行为不变的代码改善清楚了不协调的局部设计
- TDD 确保对系统的更改不会导致系统丢失或者破坏现有功能
- 持续集成 为团队保证了同一个代码库
三种实践中,重构是克服演进式设计中大杂烩问题的主力。通过在单独的类以及方法级别上做一系列小步重构来完成。我们可以很容易重构出一个独立的类来放某些通用的逻辑。但是你会很难给她一个业务上面的定义。只能给予一个解决维度的含义。这带来的问题就是新接手的人或者说新同学并不一定知道对通用逻辑的改动和获取来自该类。很明显 在代码整洁之道里面的腐败的味道。。
事实上,你可能意识到问题之所在。在解决现实问题的时候,会将问题映射到脑海中的概念模型,在模型中解决问题,再将解决方案转换为实际的代码。上述问题在于我们解决了设计到代码之间的重构。但是提炼出来的模型并没有实际的业务含义。这代表着在开发新需求的时候,其他人不能很自然的将业务问题映射到模型中。这样的设计就好像重构者的自娱自乐,代码继续腐败,然后重新重构。。。无休止的循环
用DDD可以很好的解决领域模型到设计模型的同步演化 最后再将反映了领域的设计模型转换为实际的代码
模型代表着解决实际问题抽象出来的概念模型
领域模型代表与业务相关的事实
设计模型代表要构建的系统
贫血症和失忆症
贫血领域模型:贫血领域对象 是指仅用做数据载体 而没有行为和动作的领域对象
传统的MVC分层模式。会很自然的写出过程代码。而学到的很多关于OOP理论的也毫无用武之地。使用这种开发方式,对象只是数据的载体,没有行为。以数据为中心,以数据库ER设计为驱动。实现的是对数据的查询 移动 处理 展示的过程。
以抽奖实现展开
场景:奖池里配置很多奖项,事先按照要求配置中奖概率。实现大概就是生成一个randomNum 匹配该随机数生成概率。
设计奖池和奖项的库表配置。实现业务逻辑。实现简单直接跳过。在service里面写业务逻辑。按照正常是没问题的。
简单的业务系统采用这种贫血模式和过程化设计是没有问题的。但是当业务逻辑复杂了,业务逻辑、状态会散落在大量方法中。原来的代码意图不明确。我们将这种称为贫血引起的失忆症。
更好的是采用领域模型的开发方式,将数据和行为捆绑在一起。并且和现实世界中的业务对象相映射