重温领域驱动设计的的基础知识:领域


我们总是倾向于不同意域和子域这样的基本术语的定义。在这篇文章中,我想大声思考并概述我对这个主题的看法。这些看法基于我在我们公司长达7年的DDD之旅,它对我有用。我相信它也可能对你有用。

领域Domain
“领域”一词定义了公司的整体业务领域。例如,在Internovus,我们为客户管理营销。我们提出营销策略,购买广告空间,制作广告,开展广告活动,联系潜在客户以及完成销售。我们为客户带来新客户。因此,我们的域是客户服务。Netflix的领域是娱乐。当然,公司可以在不同的总体领域工作。例如,亚马逊开始在零售业,但目前云计算也是亚马逊的域。

子域
为了实现其目标,公司必须在多个子域中工作。它们被称为子域,因为它们本身并不足以使公司取得成功; 它们共同构成了公司的业务领域。
例如,Internovus必须管理广告材料,购买广告空间,管理广告系列,优化广告系列以及管理我们的财务。我们需要执行所有这些活动,以在我们的业务领域取得成功,即客户服务。

子域类型
并非所有子域都是相同的。它们可以分为三种类型:通用,核心和支持。

通用子域
通用子域是所有公司以相同方式执行的事务。那些被认为是“解决”的问题。
在Internovus,我们必须实施身份验证和访问授权管理。幸运的是,我们不必重新实现它。我们的行业已经解决了这个问题,这些解决方案比我们在合理的上市时间内提出的任何解决方案都更加安全和经过考验。
此外,法律要求可能会限制我们并规定解决方案。例如,我们的会计子域采用,法律和法规要求规定了我们的财务管理方式。所有公司都以同样的方式做到这一点。
更重要的是,它们不是自己实施已知的解决方案,而是可以作为开源项目采用,或者作为现有的现成产品购买。

核心子域
核心子域是您组织的秘密。它们为您的公司带来竞争优势。公司希望竞争优势具有较高的准入门槛。没有人会投资他们的竞争对手可能迅速复制的东西。因此,就其性质而言,核心子域是复杂的。他们的业务逻辑很复杂,而且通常会随着时间的推移而不断变化。

技术解决方案应与核心子域的业务复杂性相匹配。您希望在此处实现最复杂的业务逻辑建模模式。您希望分析和优化算法的业务性能。要做到这一点,你需要指派最好的人来处理它们。您不希望冒险使用核心子域。市场上可能有解决方案,但您不想购买它们。根据定义,在核心子域中,您正在做与竞争对手不同的事情。如果你不是,那么你就没有竞争优势。

例如,在Internovus,我们确保优化我们的广告活动。我们希望花费最少,但却获得最多的潜在客户。我们有办法做到这一点。我们可以通过现成的产品来实现我们自己的解决方案。他们存在。但那会错过这一点。根据定义,我们管理和优化这些广告活动的方式与竞争对手不同。

支持子域
支持子域(如通用子域)不会为公司提供任何竞争优势。另一方面,没有现成的现成解决方案。虽然支持子域不提供竞争优势,但它们是实现核心子域所必需的。因此,公司必须推出自己的支持子域实现。

例如,Internovus有一个广告素材目录。该系统管理我们的设计工作室制作的所有横幅,登录页面和其他创意材料。我们不会通过编目这些文件的方式赚钱。但由于没有任何现有产品可以满足我们的需求,我们必须自己实施。
由于支持子域不能为我们提供任何竞争优势,因此它们不应该很复杂。他们的业务逻辑应该足够简单,可以通过一些快速的应用程序开发框架推出,或者完全外包用于离岸开发。
但是如果业务逻辑很复杂,充满了规则,算法和不变量呢?商务人士可能已经过度创新了他们的要求。由于该子域不提供竞争优势,因此这种复杂性是偶然的,应该简化。
但如果不能简化怎么办?这就是事情变得有趣的地方。如果支持域很复杂,并且有其复杂性的原因,那么它可能是伪装的核心子域。该业务可能会从此子域获得额外的竞争优势。

领域Domain与 子域Subdomains
在DDD蓝皮书中,术语域和子域可互换使用(例如,“核心域”和“通用子域”)。在我看来,这个措辞引起了混乱; 因此,我更喜欢使用Domain来定义公司的业务框架,而Subdomains则用于定义在公司域中取得成功所需的不同业务领域。

评估复杂性
这种对子域进行分类的方式很大程度上依赖于业务逻辑的复杂程度。但是,您在哪里划分简单和复杂业务逻辑之间的界限?不幸的是,我不知道能够提供客观答案的规模。但是,这些启发式方法可以帮助您感知差异:

  • 系统是否类似于CRUD接口,是否由领域专家以CRUD术语描述? - 简单
  • 业务逻辑是否围绕输入验证? - 简单
  • 你有复杂的算法和计算吗? - 复杂
  • 您是否有应该执行的业务规则和不变量? - 复杂
  • 结果代码的圈复杂度是什么?它有许多不同的执行方案吗? - 复杂

最后,与努力一样,有些事情在相对值中更容易估计。一旦有了一些核心和支持子域,就可以根据其复杂性来估计其他子域。
同样重要的是要注意子域的复杂性不是绝对值。这在很大程度上取决于给定公司的需求。例如,前面提到的Creatives目录对于Internovus来说非常简单 - 我们只需要一种方法来编目这些文件。但对于另一家专门从事管理和索引创意材料的智能方式的公司来说,同样的工作要复杂得多。因此,Creatives目录将成为该公司的核心子域。

特别案例
当然,一家公司可能拥有多个核心子域,如果它与竞争对手做多种不同的事情。对于Internovus,广告系列优化,潜在客户优先排序,代理商佣金管理只是我们核心子域中的三个。
可能没有在软件中实现核心子域。例如,在我们的一个副业中,我们只有支持和通用子域。该企业的竞争优势在于完全不同的方面 - 利用我们与其他公司的现有关系。因此,仔细查看并确定这些案例。如果解决方案没有提供商业价值,请不要过度设计解决方案。

“所有模型都是错误的,但有些模型是有用的。”在DDD社区中,我们倾向于像咒语一样重复这句话,但忘记将它应用于我们自己的问题和技巧。我对域和子域的看法不是绝对的事实,只是一个模型。有人说这是错的。当然,所有型号都错了!但我觉得它在很多方面都很有用。

易于分类
强调业务逻辑的复杂性简化了子域的分类过程。要进行分类,请问自己:
您是否可以在不影响公司竞争优势的情况下购买/采用现成的产品? - 通用子域。
业务逻辑简单吗? - 支持子域。
最后,如果您无法购买产品,并且子域的业务逻辑很复杂,那么它就是核心子域。

协调业务和技术复杂性
这种对子域进行分类的方法允许您将技术解决方案的复杂性与业务子域的复杂性保持一致。
对于核心子域,使用重型火炮。是领域模型或事件源模型模式。你需要他们解决复杂性的能力。
对于支持子域,请使用简单的解决方案。事务脚本或活动记录模式就足够了。此外,这些是您可以外包而不会危及业务的子域。
当然,通用子域比购买或采用更便宜而不是实现自己。

与业务对话
您可以立即向商务人士描述此模型。完成后,您可以通过简化非常复杂的支持子域来帮助优化公司的工作。
此外,您可以帮助您的企业发现新的竞争优势。如果支持子域很复杂,并且存在这种复杂性的正当理由,那么通过识别这些域,可以帮助您的组织获得更高的利润。