关于ddd+up+tdd的困惑!

最近一段时间都在看ddd和up,个人感觉使用up进行项目的管理开发,运用ddd进行领域建模,在设计阶段,运用tdd进行驱动开发,这应该是一个比较理想的开发模式,但好的东西在项目的开发中不一定会得到充分的运用。

比如up中强调的迭代开发,细化阶段经过5-8次迭代,每次迭代3周,要完成确定整体需求的90%,完成20%左右的成品代码的编写,项目风险最高、最核心的业务的需求和设计已经确定并有部分实现,剩下的在构造和移交阶段去完成。每次一迭代中又是按照ddd进行领域驱动建模,通过tdd来测试驱动开发。但是在实际开发中,很多情况是客户并不知道他需要什么,需求十分模糊,甚至只有不到一百个字的需求,需求的不断深化和挖掘需要大量的沟通和时间,而这一点首先是客户不一定做到,在客户的传统思想中,你先拿出一个整体方案看看再说,也就是系统的需求分析文档,有了需求分析文档,再看看你的概要设计,等详细设计出来后,才给你打钱。客户需求的挖掘和up强调的迭代开发是吻合的,而客户的思维是见着东西才给钱又和迭代开发的每次迭代出一个可运行的产品相矛盾,因为客户没有更多的耐心,等你一点一点去捏泥人。我记得在一本国外大师写的书中提到过盖房子的故事,一个公司选两家设计公司给他们设计房子,第一家公司一去就拿来之前才做好的一个非常不错的建设方案,有成品、有图纸,看上去效果也不错;另一家公司没有给出图纸,也没有太多承诺,它要求看客户的建设场地和需求,根据客户的需求重新量身定做一套设计方案,确保设计出来的东西就是客户想要的东西。这位大师强调说,最后取胜的一定是后面一家公司,因为他把需求放到了第一位,相对而言风险更低,成功的机会更大,前一家公司虽然有一个不错的设计方案,而且有成品展示,但是别人认为好的东西,客户不一定就认为好,用在别处成功的东西,用在这里不一定就一样会成功,所以从这点考虑,这家公司必败无疑。

我很赞同这位大师的观点,但是在国内,似乎很多公司都会选择第一家公司为自己做设计,因为他们往往没有自己的明确的需求,很多时候很容易被一些先入为主的观念所左右,所以大多数情况下,他们很轻易的相信他们所看见的,而不一定是仔细考虑他们真正想要什么,这是一个十分突出的问题!

其次,迭代开发对团队的要求很高,它需要团队成员对涉及的领域知识十分熟悉,甚至是精通领域概念,这样才能在每次迭代中做到游刃有余,而这一点上有很多公司也是望而却步,他们常常会说:这东西看上去不错,但是我们不会去用!

再次,说一个具体的问题。就是对象和关系不匹配的问题,在设计领域模型的时候,我们从面向对象的角度去分析实体、值对象,分析关联,隔离领域、确定聚合,随着对领域的不断深入理解,我们会去不断的精华模型,去改善设计,是设计更加柔性,使结构更加合理。但在对象的持久化的问题上,很多时候我们不愿意去使用hiberante这样的ormapping工具,担心hibernate在某些方面(比如性能上),不如原生sql来得高效,多数情况是使用自己开发的中间件,对jdbc进行封装,对分布式数据进行一些处理,这个时候关系模型的设计显得越发的重要,有部分重要的业务甚至放到了数据库中去存储过程实现。关系模型和对象模型在粒度上不同,导致不匹配的问题比比皆是,最终选择了一个折中的方案,看上去成了一个类一张表的样子,在使用对象的时候,对象的导航也成了一件代价巨大的事情,因为没有了hibernate这样的ormapping工具,使得从数据库中查询来的数据无法自动封装成对象,这样对象模型中的对象导航就成了一副空架子,设计的时候虽然是面向对象的东西,但真正实现起来有逐渐回到了面向过程的老路上来,这种感觉十分痛苦!

如何解决上述存在的问题呢,这是最近一直困扰我的问题,请大伙谈谈自己的看法!

>对象的导航也成了一件代价巨大的事情,因为没有了Hibernate这样的ormapping工具,
是否使用ORM框架倒是其次,有了就是开发方便提高效率,但是必须明确持久化只是对象冬眠暂时休息的
一种行为,是众多业务行为中一种通用特殊行为,这句话道理很简单,但是要转变过来很不容易的。
使用持久层技术ORM或自己的框架,严格分割领域对象业务和领域对象冬眠持久化之间的界线,不要因为
熟悉SQL,就认为使用SQl或存储过程实现业务更快,一定要告诉自己:这是先入为主的原因,自己要探索
一条针对当前这个项目的复杂Domian Model之路。

不用太担心性能,如果你真的关注对象式系统的性能,就应该引入缓存,这时你花费的力气会让你明白,不如直接使用ORM。

>但是必须明确持久化只是对象冬眠暂时休息的一种行为,是众多业务行为中一种通用特殊行为
这句话似懂非懂,需要好好体会,banq能否在深入的谈谈

不错的问题,希望banq能够深入谈谈看法..

>但是必须明确持久化只是对象冬眠暂时休息的一种行为,是众多业务行为中一种通用特殊行为

我的意思是:领域对象有很多重要本质的业务行为,不只是持久化,但是我们经常将持久化作为一个唯一依赖的行为,通过这个行为管道变相的实现很多业务功能。

见图中,一个正常的领域模型,有着丰富的各种不同业务操作,严格来说:持久化并不是业务行为,我们去问一个不懂计算机的业务人员,他的业务模型是否需要持久化,他肯定不知所云,持久化只是我们计算机人员为避免数据因为关机丢失或事务一致等原因设立的一个技术概念。

但是我们很多软件人员就死死抱住持久化这一所谓技术法宝,通过这一个唯一管道,再注入SQL这样数学式抽象表达方式,变态地实现各种模型业务行为。打个比喻:开车有5档,不同情况使用不同档,但是如果一直只使用一档开车,可不可以?可以,但这是扭曲的;再比喻:人有两只手,如果你做什么都使用其中一只手;可不可以?可以,但是这是扭曲的;业务模型有各种业务行为,你只通过其中一个通用的持久化行为实现本应该和持久化并行的其他业务行为?可不可以?可以,但这是扭曲的。

所以,我说:数据库思维和方式害了我们,影响我们正常自然的开发,OO就是自然正常开发,我们今天叫它为
OO,明天称为其DDD,后天可能又是一种称谓,不要因为它有一个称谓,就玩名词逻辑,什么OO不是万能等等,
说这话的人老子道德经开篇“名可名,非常名”可能都没有读过,名称只是名称而已。

恕我直言,楼主虽然使用DDD,但是不彻底,掺杂了关系模型,这两个是矛盾的,是水和火,前些时候也看到有人在Jdon鼓吹SQL和DDD两个都要,两个都要就是你这样的后果,所以,不从本质思维深处认识到对象和关系的不匹配,以为那只是理论上矛盾,那么实际中你将因为这个不匹配白白付出汗水和项目的失败,这些都是刻骨铭心的,这种失败的打击心情是那些纸上谈兵者所无法体谅的。

所以,楼主这种情况必须在DDD上深入,完全去除关系模型,恢复业务模型的常态,其实衡量一个领域模型是否
正常,只要让不懂计算机和数据库的业务人员看看,如果他们能够看懂,说明你的业务模型比较全面且没有关系数据库概念。





关于持久化的一个比喻:
上学的时候我们都做过一个物理试验:钟摆试验
现在的要求是记录和重现整个钟摆试验的过程
有两种办法:我用这两种办法来比较面向对象数据库和关系数据库的区别。
第一种来得最直接,也最直观,只要正常的人都可以理解——找个摄像机把钟摆试验的过程录下来,需要回顾的时候,看看录像就好了
第二种方法抽象一点,我们绘制一个坐标图,以时间为横轴,以振幅为纵轴,描出一个逐渐衰减的余弦曲线,需要回顾的时候,把这张图拿出来看看就知道了,但这不是很直接,需要一定的数学知识
好了,需求是记录和重现一个钟摆试验(持久化一个对象),第一种方法就是直接使用面向对象的数据库,对象就是直接保存到数据库中,重建对象的时候直接从库里拿出对象就可以了,很直接。
第二种方法是使用关系型数据库,通过记录对象持久化那一刻的一些关键的状态信息来间接实现对象的持久化,这些关键信息为以后重建对象提供必要的参数,相当于做了一个场景快照。当重建对象的时候,需要根据保存在关系型数据库中的参数去构造一个新的对象。

毫无疑问,面向对象的数据库是最自然的对象持久化的方案,但在关系数据库大行其道的今天,我们不得不去面对对象和关系不匹配的问题,因为我们目前还是要继续使用关系数据库来持久化各种对象。
现在回过头来看看,问题就出来了:

我们使用面向对象的方法来分析需求,分析核心业务,我这里引用banq的原话:“楼主这种情况必须在DDD上深入,完全去除关系模型,恢复业务模型的常态,其实衡量一个领域模型是否
正常,只要让不懂计算机和数据库的业务人员看看,如果他们能够看懂,说明你的业务模型比较全面且没有关系数据库概念”,我很赞同banq的观点,但是业务模型是通过一大堆的对象以及对象之间的交互来描述完成的,
业务行为的直接结果是对象状态的改变,记录对象状态的改变是我们无法绕过去的,由于采用关系型数据库来完成持久化,我们就不得不去思考关系模型和对象模型不匹配的问题,对象模型再好,解决不好对象关系不匹配的问题,模型的实现就无法真正落到实处。
也就是说,对象模型抽象的再好,还必须通过关系模型来把它落到实处。那么关系模型什么时候考虑呢,有了ormapping工具我们可以节省很多时间,如果不用ormapping工具,我们在设计对象模型的时候就必须要兼顾关系模型,寻找一个比较好的平衡点,
我的理解是这样,请banq指教

> 那么关系模型什么时候考虑呢,有了ormapping工具我们可以节省很多时间,如果不用ormapping工具,我们在设计对象模型的时候就必须要兼顾关系模型,寻找一个比较好的平衡点,


我想,在领域建模的时候也不应该去考虑关系模型,就好像在构建领域层的时候过多的考虑基础结构层的情况一样。这样只能分散对领域层的关注。对象持久化是基础结构层的一种服务,应该更具有通用性,也就是它不应该与具体业务相关。

个人拙见。

我也不同意在领域建模考虑关系模型,如果仅仅为了性能。

而且,关系模型不是一定能提高性能,否则google就用一个大型数据库了,分布式对象计算模型才是一个可伸缩的真正高性能的模型,而这些都是基于对象模型,让对象在多台服务器之间奔跑。

可见:
OO + 分布式计算 = 软件性能架构的方向
http://www.jdon.com/artichect/architecture.html