我为什么想并且要学习 Scala » Topics » 中国软件匠艺小组
说了那么多,我的根本目的还是要将Scala作为实现DDD的主要武器。那么试想一下,Scala在我们实现DDD的过程中能有哪些帮助呢?我暂且胡侃乱诌如下:
- 表示值对象、领域事件等元素更直观。值对象、领域事件在DDD里都应该是immutable的,以往多采取POCO形式表示,现在改用Scala里的
val
以及case class
表示,在语法层面就直观地表明是不可修改的。 - 在类的方法层面实现CQRS时有语法支持。用Scala里的Function(返回类型为非
Unit
)对应CQRS里的Query,保证类的方法没有副作用;用Procedure(返回类型为Unit
)对应CQRS里的Command,明确表明这一类方法会产生修改状态等副作用。这同样从语法层面就能对二者进行明确区分。 - 模式匹配丰富了函数操作。除了正则表达式,Scala形式多样的模式匹配语法,为提取数据、完成数据分组聚合等运算、实现逻辑判断提供了强大支持。比如定义
def sum_count(ints:Seq[Int) = (ints.sum, ints.size)
这样一个函数后,我们可以这样调用,以得到一个1至6的整数序列的整数值合计,及该序列的尺寸:val(sum, count) = sum_count(List(1, 2, 3, 4, 5, 6))
。 - 为实现DSL提供有力支持。Scala自带有解析框架,加上灵活的函数语法支持,要自己实现一套DSL及其相应的语法解析器将不再困难。比如在配置文件里这样的一条配置语句,表示退休条件为年龄达到60周岁或者工龄届满30年:
retire = (Age >= 60) || (ServiceLength >= 30)
。以往的方式是自己写一个语法解析器,把这条文本转换成相应的Specification对象,然后扔给聚合去使用。现在有了Scala的帮助,就使编写语法解析器这一环节的工作量大大减少。 - 合理的高阶函数设计,使规则编写得到简化。比如打折规则、费用报销规则,以往可能需要若干层的if-else嵌套,现在则将通过高阶函数得到大幅简化。对此,我强烈推荐刘光聪先生的视频Refactoring to Functions,你会在刘先生的重构过程中发现高阶函数的强大。
- Actor为高效并发打下基础。Actor内部完全自治,自带用于存储消息的mailbox,与其他Actor只能通过消息进行交互,每个Actor都是并发的一个基本单位。这些特点,非常适合于采取Event Sourcing方式实现的DDD。每个聚合都好比一个Actor,在聚合内部始终保持数据的强一致性,而在聚合之间交互的领域事件则好比Actor之间的消息,聚合之间借由领域事件和Saga保证数据的最终一致性。
- Trait成为AOP利器。Trait是Scala的另一大特色,它就象AOP织入一样,能动态地给某个类型注入方法或者结构。比如配合类Circuit和with后面那4个Trait的定义,
val circuit = new Circuit with Adders with Multiplexers with Flipflops with MultiCoreProcessors
这样就创建了一个带有加法器、乘法器、触发器和多核处理器的元件。 - 隐式实现为类型扩展提供支持。对应C#里的静态扩展方法,Scala通过
implicit
为实现数据类型的方法扩展提供了便捷,成为Trait之外的另一个功能扩展手段。 - 能降低常见BDD框架的学习成本。尽管这一点可能比较牵强,但我正在努力摸索如何将BDD与DDD结合,而常见的Cucumber、Spock等一些BDD框架,其语法与Scala比较相近,所以我才有如此一说。
Read full article from 我为什么想并且要学习 Scala » Topics » 中国软件匠艺小组
No comments:
Post a Comment