领域驱动设计中的重构


10

我刚刚开始从事一个项目,我们正在使用领域驱动的设计(由Eric Evans在“ 领域驱动的设计:解决软件核心中的复杂性”中定义。我相信我们的项目肯定是该设计的候选人就像埃文斯在书中描述的那样。

我在不断重构的想法中挣扎。

我知道在任何项目中重构都是必不可少的,随着软件的改变,重构将不可避免地发生。但是,根据我的经验,重构是在开发团队的需求发生变化时发生的,而不是对领域变化的理解(Evans称之为“重构以获得更大的洞察力”)。我最关心的是对领域模型的理解方面的突破。我知道进行小的更改,但是如果需要对模型进行较大的更改怎么办?

在说服更清晰的域模型之后,应该说服自己(和其他人)重构的有效方法是什么?毕竟,为了改善代码的组织或性能而进行的重构可能与无处不在的语言代码的表达方式完全不同。有时似乎没有足够的时间进行重构。

幸运的是,SCRUM使它可以进行重构。SCRUM的迭代性质使其易于构建一小块并进行更改。但是随着时间的流逝,该片段会变大,如果您在该片段太大而又难以更改时又取得突破,该怎么办?

是否有人从事采用领域驱动设计的项目?如果是这样,那么对此有所了解将是很棒的。我特别想听听一些成功的故事,因为DDD似乎很难解决。

谢谢!


如果您编写的代码认为您无论大小都无法更改,请停止。
JeffO 2010年

@Jeff:不能更改它不是问题,随着代码的增加,更改它的时间和资源都是问题。
Andrew Whitaker 2010年

2
如果要添加代码,而又知道现有代码需要重构,而不必重构,那将带来风险。这并不意味着它将无法正常工作。
JeffO 2011年

Answers:


9

我一直是DDD的忠实拥while(使用或不使用测试框架的安全网)。

重构的整个概念和生命周期不会改变,因为您现在正在使用一种新的设计方法。如果要花费大量时间,则必须从项目中获得一定比例的收益,以便从管理层那里获得时间。

关于这样做:在一个实例中,由于对领域模型的理解上的“突破” ,我参加了为期3 个月的重大重构。它要求进行测试以验证当前行为,进行测试以验证预期的行为以及对调用代码的更改。但是,好处是巨大的,它使企业可以做很多以前需要做的事情,但以前做不到。本质上,重构本质上是一个“功能”。


很高兴听到您成功进行了如此大的重构。听到您必须进行如此大的更改,这也很高兴。这就是我所说的重构。长达数月之久,影响巨大。
Andrew Whitaker 2010年

重构是一项功能,我会记得。
FilipDupanović2011年

5

我认为域驱动设计中的重构是出于需求而非“好的”重构。一旦您识别出错误的域模型,该代码/系统就不代表实际问题。

举例来说,我们最近致力于合理领域复杂性的应用程序。这是一个计费/合同系统,我们正在引入一种新型的费率。我们使用的是敏捷过程,准确地说是2周的Scrum。

最初,我们在模型中确定了这两个比率是完全独立的,除了通过合同以外,没有任何关系。但是,当我们完成更多故事后,我们意识到它们实际上是相同的,特别是当我们开始将新汇率打包为旧汇率以使其正常工作时。这是第一个警告信号。

简而言之,我们可以使用错误的模型完成90%的故事,但是到了关键点,在代码的每一部分中,我们要么都将新的Rate打包为旧的Rate,或者创建newRate或oldRate的每个位置。我们撞在那堵砖墙上。我们在项目的这一部分已经完成了一半,并且知道完成时间将是指数的,或者对于不正确的域模型而言是不可行的。因此,我们忍无可忍,将一个故事分解为其他八个故事,并重构了域模型。

当我们完成该项目时,从事后的眼光中我们知道这是正确的事情,也是唯一可以正确实现的事情。

需要时间吗?是的,但是如果我们不这样做,那将花费更多时间。DDD做对了吗?好吧,很有趣,我们当时不了解DDD,但是不久之后,我们参加了Eric Evans的DDD研讨会,我和我的同事所能做的就是点头。我认为,如果我们知道DDD,我们会提早进行重构,从而节省更多时间。


好答案。我们每隔几个月就会经历一次与此类似的事情。很高兴知道我们并不孤单!
Andrew Whitaker

3

如果您在域模型中遇到问题,对其进行纠正很重要。以我的经验,当我们实现某些模型时,我们会漏掉领域模型如何连接到其不同实体的信息。

结果是,人们习惯于使用建模所不希望的方式进行建模,从而破坏了模型的其他部分,试图“使其正常工作”。

一旦您意识到域模型中存在问题,请尽快对其进行更改。重构之前花费的时间越长,针对用户进行更改的难度就越大,现在已经适应了他们的思维模型。


3

对于代码的某些部分,连续重构是多余的。对于代码的其他部分(在DDD中,所谓的Core Domain)是必要的。理解代码不是应该的方式,这会给开发人员带来额外的认知负担(我们对领域的理解与当前实现之间的区别),这将使进一步的开发更加困难和/或昂贵。

问题是:“将需要这些进化吗?”。在核心域(使业务有所作为的领域)中,答案是“是!”。因为这是企业更关心的领域,并且将对利益相关者有所作为。由于您的域模型具有灵活性,因此您可以在此处将代码保持完美的形状,并以最小的努力准备实现下一个需求。

但是,当将其应用于所有应用程序代码时,这将是昂贵的。对于业务而言不那么重要的领域(DDD术语中的支持子域通用子域)可能需要比为核心保留的方法复杂的方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.