DDD系列-聊聊敏捷开发模式的缺点
敏捷开发模式
在我以前的软件开发经验中,很多软件都是基于分层思想+贫血模式设计的(如下图),也许从入行开始就一直是这样,也并没有发现什么问题。
一句话总结以前的开发思路:"表建好了,代码也就写好了"
敏捷研发流程
一般从需求开始(其实是局部的需求,RD往往没有全局信息),产品同学将需求分析完和开发同学进行需求评审,评审完毕后开发同学开始基于需求进行技术方案设计。这时候一般会落到数据库设计,将库表设计完毕。设计完表之后,我们常说的"Dao层"就有了,接下来就进行逐层向上开发,最后封装出一个api接口。
这时候你会发现真的是"表建好了,代码也就写好了",数据驱动开发或者说是一种基于数据模型的开发。这种开发模型所有的业务逻辑都堆砌在Model层,其实可能开发者本身都没理解这一层的含义,因为Controller层不能直接穿透到Dao层,所以不得不在Model层继续傻瓜式封装一下dao层
敏捷研发最有价值的产出
由于敏捷开发基本是基于数据驱动开发的,所以它的设计基本就是敏捷需求开发的最有价值的输出了,例如客户下单的需求为例子
敏捷开发的舒适期
这种开发方式在创新项目的前期,非常适合用这种方式,因为首要任务是项目能够活下来,不要被淘汰掉。这种模式就非常适合低成本
快速迭代起来,并且新人这个时候是友好的,从api入口开代码能够一口气看下来,逻辑基本上就明了了。
敏捷开发的阵痛期
如果跨过了舒适期,来到阵痛期,恭喜你,至少项目活下来了。这个时间开发和迭代变得非常困难了,更有甚者,一张表的扩展字段可能达到恐怖的100多个了(笔者曾经所在的公司)。这个时候没有一个新人来了不骂娘的,因为根本不可能是正常人能理解的东西了。整个大项目来到一个大单体时代
1)大单体-拆表:治标不治本,只是解决容量问题,对业务的复杂度是没有贡献的
2)大单体-拆微服务(伪服务):为什么说是伪微服务,把dao层暴露api接口作为一个一个服务,然后让大单体接入,后面介绍DDD会知道,这只是改变了调用方式,根本对减少业务复杂度没有任何贡献,反而因为网络请求增加了复杂度
3)大单体-拆微服务(局部拆分):比如电商中的收件人作为微服务,然后包含了各种冲突,融合,关系等完善的服务。然后用这个新微服务潜入到大单体中。这也是死路一条,后面介绍DDD会知道,它改变了模型(虽然作者可能都不知道隐含的模型),模型的改变必然导致业务逻辑改变。但是PM可一口咬定这是技术项目,业务逻辑改变他自己也没想到。
好像陷入了迷茫期......
敏捷开发的转型期
注意,业务一定要够复杂才需要转型,最好是陈年老单体,比如笔者以前所在的公司把新招进来的10年工作经验的资深开发给整不会了。这种大单体业务逻辑非常复杂,谁都知道,唯一的出路是重构,然后将大问题拆解成更多的小问题。可是怎么重构,变成了一个非常大的挑战。
我们思考以下的问题
1)我们是不是离业务太远了,几乎尝试的全部重构方式都市技术人员的自娱自乐
2)公司的战略呢,如果公司的未来战略是发展另一种形式的电商,那我们是不是努力错方向了
3)我们的业务知识没有沉淀下来,比如我问你"债权"以及包含的关系,可能在你的代码里并没有任何体现
4)拆分拆分,可是如何拆分,拆分的原则到底是什么
5)最重要的,汇报的时候画的架构图简直不能再高大尚,可能跟代码架构完全对应不上,你让新人情何以堪
好像还是陷入了迷茫......
目前市面上公认的DDD能够比较好的解决上面的问题,至少在架构师层面它非常有指导意义。DDD能联动公司战略,领域划分,领域建模,标准架构分层实现,使得领域专家(运营/PM),架构师,开发人员一起协同完成。在DDD的视角里,领域模型将变成第一主角,合理建模已经如何界限上下文变成了工作的重点。而表设计在DDD中仅仅是一个技术细节,将变得不在重要。
再看敏捷开发
其实敏捷开发更像是一种宣言,其实敏捷开发是可以产出很完美的结果的,敏捷的价值观
个体和互动 高于 流程和工具;
工作的软件 高于 详尽的文档;
客户合作 高于 合同谈判;
响应变化 高于 遵循计划;
其实有不少人在敏捷开发的时候是有面向对象开发的,并且做的也非常不错,注意这里说的面相对象不是使用java等面相对象语言开发,而是使用瀑布流中的建模步骤来进行软件的设计
面相对象开发其实就对应着DDD所提倡的建模,这一点来看其实DDD不是新鲜的。还有一点敏捷开发忽略"语言"在DDD看来非常重要,DDD的期望是运营+PM+研发层面保持一致的语言,然后用这个统一语言贯穿所有的环节。
所以在笔者看来,敏捷开发和DDD不冲突,甚至DDD有的时候也提倡在小黑板上快速建模。在DDD落地的时候,依然可以保持敏捷开发的模式。
No Leanote account? Sign up now.