领域驱动设计之我见
开这个新帖子的诱因,是《寻找答案之DDD》的发贴者要我写的图书管理系统的原型代码。 因为这个案例足够小,而且在学校,我们一般都有借书的经历,对图书管理系统所要表达的领域有充分的认识,可以判断设计出来的领域模型是否优雅,是否接近客观领域的本质。
《寻找答案之DDD》中引用了敏捷之道的张逸先生使用DDD方法设计的图书管理系统的领域模型,张逸先生是位验丰富的程序员,以前看过他的一篇文章《什么是好的代码》,里头有一个观点,好的代码中每个方法最好不要超过5行。这个量化的指标,要完成挺难的(完全做到可能也没有必要),我只能尽力而为。MVC和DCI的提出者Trygve Reenskaug提倡用可读性极佳的代码直接捕获用户心中的模型,我采纳了这个观点,同时在编写原型时借鉴了四色原型及DCI的部分思想。
这里先陈述我的一些思考和观点,可能与一些经典著的定义有所出入,随后再将代码贴出来。
1)领域是客观的,不以人的意志为转移,但人之于领域具有能动性,可以认识和改造它。
2)领域模型是主观的,体现了程序员对领域的认识,是程序员心中对领域的素描。
3)用户需求是主观的,体现了用户对领域的认识,是用户心中对领域的素描。
4)领域模型需要捕捉和包容用户需求。领域模型与用户需求的关系十分重要,下面展开来讲。
“用户需求”是对领域的“素描”,用户的需求来自对领域的“诉求”,这些诉求往往是深刻的,因为其来源于用户对领域长期观察和使用的经验,比起我们程序员,一般更完整、更真实地接近领域的本质。我们对“用户需求进行素描”,就是“借鉴用户的宝贵经验”,可以更快、更好地素描客观领域,这可以说是一条认识(未知)领域的捷径。但是当用户需求不明朗或不清晰时,我们需要超越“用户需求”,对领域进行深入的摸索,去寻求更清晰的视角,对领域进行刻画。
此外,“用户需求”不能等同于“用户”,捕捉“用户心中的模型”也不能等同于“以用户为核心模型”,这是不同的概念,不能忽略其差异。《老子》书中有个观点:有之以为利,无之以为用。在这里,有之利,即建立领域模型;无之用,即包容用户需求。举些例子,一个杯子要装满一杯水,我们在制作杯子时,制作的是空杯子,即要把水倒出来,之后才能装下水;再比如,一座房子要住人,我们在建造房子时,建造的房子是空的,唯有空的才能容乃人的居住。我们建立领域模型时也要将用户置于模型之外,这样才能包容用户的需求。
在图书馆管理系统的领域,借书人(Reader)即用户,建模时应该将其置之于外(借书人在系统中的镜像可以考虑放在应用层实现),借书卡(Card)是该领域一个重要的模型,借书人可以使用它进行借书。我的设计与张逸先生的设计差异很大,考虑到其具有丰富的经验,所以我不能断言我的设计是否更接近于领域,下面我将代码原型贴出来,因为只是用来示意和讨论的,所以有些实现做了简化。欢迎各路神仙进行评断、深入探讨,如果张逸先生本人也可以来到这里参与讨论,最好不过了。
推荐其博客,内容极其丰富。
http://www.agiledon.com/post/2010/06/107.html