最佳做法

Domain 驱动设计简介

David Laribee

本文讨论:

  • 从无处不语言建模
  • bounded 的上下文和聚合的根目录
  • 使用单个的责任主体
  • 储存库和数据库
本文涉及以下技术:
Visual Studio

内容

Platonic 模型
讨论在说话
上下文
知道您值主张
在系统的单个的责任
实体具有的标识和一个生命
值对象描述信息
聚合根目录合并实体
域服务模型主操作
存储库保存并 Dispense 聚合的根目录
数据库的内容
Getting Started with DDD

域驱动设计 (DDD) 是原则和模式帮助开发人员工艺品明确对象系统的集合。正确应用它可能会导致软件抽象称为域模型。这些模型封装关闭业务现实情况和代码之间差异的复杂的业务逻辑。

此文章中, 我将介绍的基本概念和 germane 到 DDD 的设计模式。这篇文章视为温和简介设计和发展丰富的域模型。为了讨论某些上下文我使用与我所熟悉的复杂业务域: 保险策略管理。

如果使用的方法此处提供吸引力要我强烈建议 deepen 通过阅读 Domain-Driven Design: Tackling Complexity in the Heart of Software,您工具箱由 Eric Evans。以上只是信息的在原始简介 DDD,是信息的一个行业的大多数经验丰富的软件设计人员的珍宝 trove。模式和核心原则,我将讨论本文中的 DDD 的派生自此简介册中详细介绍的概念。

剪切环境的体系结构的需要

bounded 的上下文不必进行组织仅由应用程序的功能区域。它们在将系统实现所需的体系结构示例非常有用。此方法的典型示例是同时具有强大的事务性占用和报表的组合的应用程序。

就经常需要在这些情况下 (这可能非常经常发生) 准备好从事务数据库报告数据库。要以开发可靠的报表寻求正确标准化程度自由,并且想要使用的对象关系映射器,以便您可以保留编码在面向对象的模式中的事务的业务逻辑。可以使用一种技术如 Microsoft 消息队列 (MSMQ) 发布来自该模型的数据更新,并将它们合并到适合报告和分析目的的数据仓库。

这可能会作为一个当某些,但使数据库管理员和开发人员以及获取。bounded 的上下文为您提供的此 promised 土地的概述。如果您感兴趣体系结构的绑定上下文我强烈建议保留选项卡上Greg 年轻人博客. 他的非常经验 articulate 有关此方法,并产生大量内容的主题。

Platonic 模型

由于我们只您开始关闭此,有意义实际定义我模型意味着。回答这个问题导致我们在简短的 metaphysical 过程。用户优于 Plato 以引导我们?

Plato 的最著名的学生的苏格拉底,建议的概念、 人员、 位置和操作我们 Intuit 和小写与我们 senses 都只是真实的阴影。他称为真正的事情的这个想法窗体。

若要说明窗体,Plato 将使用什么成为称为该 cave 的 allegory。此 allegory,存在内深度、 深 cave 绑定的一个人。用户链接方式他们可以只曾经看到从打开接收指示灯,cave 的空白墙壁这些 cave。当一个动物遍历打开的时阴影被预计到内部墙壁 cave dwellers 看到的。在 cave dwellers 这些阴影很实际的事情。一个 Lion 遍历的时, 它们指向该 Lion 阴影,并 exclaim"运行的封面"! 但它实际上是仅实际窗体本身,Lion 的阴影。

窗体的 Plato 的理论上可以与 DDD。其指南的许多措施有助于随着时间的推移获取接近理想模型。路径要用您的代码说明在窗体是有关分散在域专家的脑海、 利益相关者的愿望和我们处理的行业的要求。这些是,非常真正意义上来 Plato 的虚 cave dwellers 阴影。

此外,您都通常受编程语言和时间和预算在尝试访问该窗体的注意事项。并不的大部分说这些限制是相当于 cave dwellers 仅能够看到阴影的内的墙的扩展。

很好的模型具有许多独立于其实现的属性。该事实,每个人的头中的模型匹配并且您正在执行代码的模型首先建模器应了解的 aspiring 域。

您创建该软件不可真正的模型。它是只有一个 manifestation 阴影如果您将您打算实现应用程序窗体。即使的完美的解决方案的一个模仿可以设法随着时间的推移 True 的窗体使代码更靠近。

在 DDD,此概念称为模型驱动设计。模型的地了解是在代码中改进的。域驱动设计器将而不费心大量文档的粗线绘制图表工具。在查找,相反,到 imbue 直接在其代码的域了解他们理解。

捕获该模型的构想是代码的 DDD 的核心。通过使软件重点手头的问题和限制为解决这一问题,得到了软件 receptive 新的见解和 enlightenment 的时间。我喜欢 Eric Evans 调用它: crunching 到模型的知识库。时您了解有关域的重要内容,您会知道右转的位置。

讨论在说话

让我们检查的一些技术 DDD 用于实现此目标。作为一名开发人员的您作业的一大部分正在与非译码器了解打算提供。如果您使用任何类型的过程与组织中,可能有要求以用户文章,任务,或用例。任何类型的要求或您会收到的规范是它通常完成?

通常要求是有些渴或表示在了解的高级别上。设计和实现解决方案的过程中很有用当开发人员具有使一些专业知识,请在目标域中的用户的访问。这是完全通常表示根据向此模板的用户文字部分的点: 作为一个 [角色] 我希望 [功能] 因此 [福利]。

让我们看的保险策略管理域中的一个示例: 为一个 underwriter,我希望策略的审核控制,以便我可以编写安全的 exposures 并拒绝危险的。

是否有人了解什么意味着?我知道我未在我看到了它编写,并确定优先级别。如何可以您可能知道需要转到从该抽象的说明提供支持的软件的所有内容?

用户案例,正确完成,将与其作者进行对话的邀请) 用户。这意味着在转从事拒绝批准 / 策略功能时应理想情况下可以访问一个 underwriter。underwriters,该的入门的是域专家 (至少很好的是) 的确定特定类别的风险是否安全的来覆盖的运营商。

当您开始讨论功能与您 underwriter (或 whomever 您项目域专家可能),付薪尤其是关闭注意到在 underwriter 所使用的术语。这些域专家使用公司或行业标准术语。在 DDD,此词汇称为无处不语言。作为开发人员,要了解此词汇和不仅时使用与域专家来说但还看到相同的术语反映在您的代码。如果在对话中经常使用,术语"类代码"或"速率设置"或"风险",我会希望在代码中查找相应的类名称。

这是一个很基本模式 DDD。在第一次 blush 无处不语言看起来像一个明显的事情,可能性您的已 practicing 这直观的一个好。但是,很重要的开发人员业务语言代码中使用 consciously 和 disciplined 规则。这样可以减少业务的词汇和技术术语之间断开连接。如何将成为下属什么,并且您保持更接近于您的工作的原因: 提供业务价值。

上下文

开发人员都,在某种意义上组织者。为解决问题的抽象 sling 了代码 (希望与目的)。设计模式、 分层的体系结构和面向对象的原则等工具为一个框架将顺序应用于 evermore 复杂的系统。

DDD 扩展您组织的工具箱,并从公认的行业模式 borrows。我所组织的模式,DDD 展示了最是有解决方案的详细信息每个级别的系统中。bounded 的上下文将指导您的软件的思想为模型的组合实现。模块帮助您组织到较小的块的较大的单个模型。稍后,我将介绍聚合的根目录作为组织几个高度相关类之间的小协作的技术。

在大多数企业系统中有课程粒度的职责范围的区域。DDD 调用此顶级组织绑定上下文。

工作者 ' 补偿保险策略需要考虑元素 (如:

  • quoting 和销售
  • 常规策略 (续订、 终止) 的工作流
  • 审核工资估计
  • 季度 self-estimates
  • 设置和管理率
  • 向佣金颁发机构和代理程序
  • 记帐客户
  • 常规记帐
  • 确定可接受 exposures (保险)

哇。这是很多内容 !未能将所有这些合并到单一的单一的系统,但操作因此引导您下 foggy amorphous 的路径。他们聊天有关与工资审核的上下文中的一个策略的常规流的上下文中的策略时,用户讨论两种完全不同的操作。如果您使用相同的策略类,您是 fattening 该类的配置文件从并获得长方式尝试-和-True 最佳操作 (如作为单个的责任分摊原则 (SRP)。

无法找出并通常避免绑定上下文的系统单到的体系结构的形式,(amusingly 称作 Mud 的大球。在 1999 年,Brian 英尺和 Joseph Yoder 定义体系结构的样式 (或 anti-architectural 样式,该情况可能) 相同名称的其经典白皮书中 ("大 Ball Mud 的").

DDD nudges 您确定上下文和限制特定的上下文中您建模工作。可以使用称为一个上下文映射在简单图来了解我们的系统的边界。我已枚举所涉及的完全功能的保险策略管理系统上下文并图 1 转这从文本的说明到 (偏) 图形上下文映射。

fig01.gif

图 1 从限定上下文上下文映射

您注意到在不同的绑定上下文某些键关系吗?这会是有价值的智能,因为您可以启动使了解的业务和体系结构的决策,例如打包和部署设计 ; 选择的技术用于封送模型 ; 和可能的大多数之间的消息重要,在您选择设置里程碑并部署工作、 时间和出。

一个上次有关绑定上下文但非常重要的想法: 每个上下文拥有其自己无处不的语言。值得区分与核心工作流中的该策略在审核子系统中策略的概念,因为它们是不同的操作。而它们可能会有相同的标识,值对象和子实体 (详细一段中) 对通常大大不同。因为您正在建模环境中,您还需要语言来提供该上下文内的精度,以便您可以与域专家,您的团队的高效通信。

更加紧密地结合比其他模型组中的某些方面。模块是一种组织特定的上下文内的这些组,充当小型边界要停止并考虑与其他模块的关联。它们还是引导您离开"的 Mud 进行小球"的另一个的组织技术。 technologically,模块可以很容易地创建 ; 在 Microsoft.NET Framework 中它们只是命名空间。但标识模块的画需要花一些时间,用您的代码。最终可以看到我们可以看到为模型时,您可能考虑内容划分为命名空间中的 mini-model 的一些事项。

为内聚性模块 teasing 分开的模型在 IDE 中具有好效果。即,因为您需要使用多个用于显式包含模块语句获得更简洁 IntelliSense 体验。它们还提供一种查看系统使用如 NDepend 的静态分析工具的更大的概念块区之间的关联。

组织的更改引入到您的模型应提示您参与某些 pragmatic、 成本优势考虑。当您使用模块 (或命名空间) 将设置您的模型时, 确实需要问题是否您正在处理一个单独的上下文。从另一个上下文 cleaving 的成本都通常更高: 现在您有两种模型可能在两个程序集中,您要连接到应用程序服务控制器,等。

anti-Corruption 层

一个 anti-corruption 的层 (ACL) 是建议您创建的工作,以防止非域概念泄漏到您的模型的网关守卫的另一个 DDD 模式。它们保留在模型干净。

在他们的心储存库是 ACL 的实际一种类型。它们保留 SQL,或对象关系映射 (ORM) 构造外的您的模型。

ACL 是引入 Michael Feathers 调用,他簿 Working Effectively With Legacy Code,一个接缝一个好方法。一个接缝是代码的其中您可以开始 cleave 关闭某些旧的代码和开始介绍 changes.finding 缝焊一起隔离核心域,可以很非常有用,使用 Refactor DDD 技术时提高您最高值部分的一个区域。

知道您值主张

大多数开发商店有经验丰富的 businesspeople 和顶部的开发人员能够隔离和描述的问题和构建的明确的、 易于维护的面向对象的解决方案的少量。客户为了获取最大的感叹号,您想以确保了解您的应用程序的核心域。核心域是应用 DDD 大多数值的绑定上下文。

在任何给定的企业系统有比其他更重要的某些方面。更重要的区域往往会分为客户端的与核心 competencies 的对齐方式。很少见业务将运行自定义常规会计软件。但如果该业务位于保险 (准备与我前面的示例) 和提供在管理的各成员之间分配责任的风险池其资金进行,然后他们有更好地是 darned 擅长拒绝错误的风险和标识的趋势。或可能有一个医疗声明处理器的客户端,而其策略是 flank 其竞争价格的自动化 amplify 其 Bill payor 员工的工作的付款。

任何行业、 公司或客户端具有在市场上的某些边缘,并且您发现自定义的软件,通常是此边。该自定义的软件是,您可能查找和模型核心域。

我们可以衡量我们投资在另一个的维度中的值即其中我们投资在到达技术优异我们知识资本。太多次高级开发人员是人员的获取 obsessed 与新技术的类型。在某些这则量应该在行业 innovates 以一个 relentless 的速度和供应商免经常发布满足客户的需求与保持竞争力的新技术产品。在的挑战我看到了它,面向的是系统的高级开发人员掌握的基本原则和模式的核心值。吸引力于最新的框架或平台中, 获取换但我们需要记住这些事情是,因此我们只是可以相信它们工作,因此供应商生成。

在系统的单个的责任

我已提到 DDD 用于模式语言结构化格式域模型。通过实施这些模式,免费,获得一定级别的 SRP 遵循,而这当然重要。

SRP 鼓励获取在一个接口或类的核心目的。它将引导您向高 cohesion,当一很件事情使代码更易于查找、 重用,和维护。

DDD 标识某些类型的图案的核心集合中的类责任。我将介绍多主的一些现在,但值得一提有 Eric Evans 原始簿从类级别范围到体系结构中所述的多个模式。介绍用于我会保留在类级别涵盖实体、 值的对象、 聚合的根,域服务和储存库。因为这是介绍,我将仅介绍使用一到两个代码示例或提示每个每个模式的责任。

实体具有的标识和一个生命

实体是您的系统中的"操作"。它通常非常有用考虑这些方面的名词: 用户位置,和,操作。

实体同时具有标识和一个生命周期。是例如如果我想要访问我的系统特定客户,我可以请求的用户数。我完成一个贸易的订单时, 它将是然后失效到我的系统,并可以转到长期存储 (历史记录报告系统)。

将实体为行为单位而非数据单位。尝试将您的逻辑放入拥有它们的实体。大多数情况有应接收某些操作,您尝试将添加到您的模型的实体或新实体 begging 创建或提取。在更多的 anemic 代码您会发现大量的验证从外部的实体的服务或管理器类。一般情况下,我更倾向于从此实体中,您获得与封装的基本原则的所有优点,并您要使您的实体行为。

有些开发人员被 bothered 的依赖项在其实体中。显然,您需要创建您的系统中不同实体之间的关联。是例如您可能需要一个产品实体获得策略实体,以使您可以确定明智策略上的默认值。当需要一些外部服务来执行内部某个实体的行为时,用户似乎会关闭非常。

我,一个,将不无穷无尽需要涉及到其他的非实体的类,然后我将尝试避免提升外我的实体的中央行为。您应始终记住实体是本质上行为单位。该行为作为一种类型的状态机的实现通常) 调用的命令的实体时, 它负责更改其内部状态,但有时需要获取其他数据,或者实施在外部世界的副作用。完成此我首选的方法是提供依赖关系,以命令方法:

public class Policy {
  public void Renew(IAuditNotifier notifier) {
    // do a bunch of internal state-related things,
    // some validation, etc.
    ...
    // now notify the audit system that there's
    // a new policy period that needs auditing
    notifier.ScheduleAuditFor(this);
  }
}

此方法的好处是您不需要为您创建的控件 (IOC) 容器的一个反转。 另一个完全可以接受的方法,在我看来,是使用定位程序服务来解决方法内的 IAuditNotifier。 此方法具有使接口干净,优点,但我发现以前策略告诉我更多信息我依赖项很多较高级别。

值对象描述信息

值对象是标识符或建模的域中的重要属性。 与实体,不同它们没有标识,; 它们只是说明没有标识的。 是否更改名为"三十五个美元"实体或者递增的科目的余额?

部分值对象是美的它们在更明确需要显示方式描述实体的该属性。 Money,一个常见的值对象看起来得好作为函数参数资金转移 API 与小数。 当接口或实体的方法中发现它时,您知道您正在处理立即。

值对象是不可变的。 在创建后,它们是无法更改。 为什么是它重要它们是不可变? 随着值的对象查找忙副作用的函数,而另一个概念借用的 DDD。 当您添加 ¥20 ¥20 时,您将更改 ¥20? 不,您正在创建新的资金描述符的 ¥40。 C# 中可以如 图 2 所示,强制永久性和释放副作用的函数,公共字段上使用只读的关键字。

图 2 使用只读,以强制永久性

public class Money {
  public readonly Currency Currency;
  public readonly decimal Amount;

  public Money(decimal amount, Currency currency) {
    Amount = amount;
    Currency = currency;
  }

  public Money AddFunds(Money fundsToAdd) {
    // because the money we're adding might
    // be in a different currency, we'll service 
    // locate a money exchange Domain Service.
    var exchange = ServiceLocator.Find<IMoneyExchange>();
    var normalizedMoney = exchange.CurrentValueFor(fundsToAdd,         this.Currency);
    var newAmount = this.Amount + normalizedMoney.Amount;
    return new Money(newAmount, this.Currency);
  }
}

public enum Currency {
  USD,
  GBP,
  EUR,
  JPY
}

聚合根目录合并实体

聚合的根是实体的一种特殊的使用者直接指向。 标识聚合的根目录,可以避免 over-coupling 由因此有一些简单的规则组成您的模型的对象。 您应该注意聚合根 zealously 保护其 Sub-entities。

请记住该最大规则是实体的聚合的根是实体的到您的软件可能充当一些引用的唯一类型。 这有助于避免的 Mud 大球,因为您现在具有阻止创建紧密结合的系统的约束其中所有内容都有与所有其他的关联。

假设我有称为策略的实体。 和,策略获取上一年度的术语的更新,因此可能实体调用期间。 由于一段不能存在没有一个策略,并且对期间通过策略进行操作,策略称为聚合的根,并且期间是相同的子级。

我喜欢我聚合根目录到出它只是认为。 请考虑访问策略聚合根此使用者代码:

Policy.CurrentPeriod().Renew() 

我在尝试更新的保险策略,撤回的保险策略管理核心域的类关系图。 请注意我如何 dotting 我我要调用的行为方式?

有几个这种方法的问题。 首先,我要清楚地违反 Demeter 法则。 一个对象 O 的方法 M 应调用以下类型的对象的方法: 本身,它的参数,它创建或实例化,任何对象或其直接的组件对象。

难道深度 dotting 种方便吗? IntelliSense 是 Visual Studio 和其他流行的 IDE 最棒的、 最有用的功能之一,但启动 dotting 实际上要调用该函数在方法时, 您引入离合器系统中不必要。 在前面的示例我现在依赖于策略类和期间的类。

对于进一步阅读,Brad Appleton 有可用的极好文章介绍更深入的含义 theories,工具,并围绕 caveats 其网站上, Demeter 的法律.

cliche"不使用由一个剪切"是潜在的维护 nightmare 过耦合的系统的好说明。 当您创建不必要的引用,都通过位置时, 您还会创建一个位置中的更改导致的更改都通过使用者的代码的级联严格模型。 未能完成与同一个目标,如远为我担心,更表达一些代码:

Policy.Renew()

查看如何将聚合只计算它出? 在内部它能够找到该当前期间并且已续订句点和其他任何需要进行。

我发现我没有单元测试使用技术如行为驱动开发 (BDD),我聚合根目录我的测试趋势实现更加黑盒和状态测试模式。 聚合的根目录和实体通常最终为状态机,并行为相应地匹配。 我最终状态验证、 添加,和减法。 还有相当一段将在 图 3 ,和它的续订示例非常清除方式您可以快速此测试的 BDD 样式中的行为。

图 3 测试聚合根

public class 
  When_renewing_an_active_policy_that_needs_renewal {

  Policy ThePolicy;
  DateTime OriginalEndingOn;

  [SetUp]
  public void Context() {
    ThePolicy = new Policy(new DateTime(1/1/2009));
    var somePayroll = new CompanyPayroll();
    ThePolicy.Covers(somePayroll);
    ThePolicy.Write();
    OriginalEndingOn = ThePolicy.EndingOn;
  }

  [Test]
  public void Should_create_a_new_period() { 
    ThePolicy.EndingOn.ShouldEqual(OriginalEndingOn.AddYears(1));
  }
}

域服务模型主操作

有时必须操作或没有一个标识或生命周期在您的域中的进程。 域服务提供一种工具为建模这些概念。 它们通常无状态和高一致,通常为集上的动作中提供一个公共方法和有时重载。

我喜欢使用几个原因的服务。 当有不依赖项的一个数量所涉及的一种行为并无法找到将该行为的实体上一个自然位置时,我将使用一种服务。 在有关过程或操作作为第一顺序概念我无处不语言讨论,我将问题是否服务意义为业务一个中心点的流程模型的。

您可以使用在续订的情况下的域服务。 这是可选的样式。 而不是将一个 IAuditNotifier 直接到策略实体的方法的方法的续订方法,您可以选择提取为我们处理依赖项解析的域服务 ; 更自然为我们要解决与实体的 IOC 容器中的域服务。 此策略使得更有意义我有多个的依赖项,但我将仍显示可选。

下面是一个简短域服务的示例:

public class PolicyRenewalProcesor {
  private readonly IAuditNotifier _notifier;

  public PolicyRenewalProcessor(IAuditNotifier notifier) {
    _notifier = notifier;
  }
  public void Renew(Policy policy) {
    policy.Renew();
    _notifier.ScheduleAuditFor(policy);
  }
}

在开发环境,Word 服务是一个高重载的术语。 有时我认为服务的面向服务的体系结构 (SOA) 所示。 我将服务视为一些类,不代表一个特定用户、 位置或在我的应用程序中的内容,但的倾向于 embody 进程其他时间。 域服务通常会在此后一类别中。 它们往往会将命名动词或域专家引入无处不语言的业务活动。

应用程序服务而在另一方面,是引入了采用分层体系结构的一个好方法。 它们可用于域模型中的数据映射到客户端应用程序所需的形状。 是例如也许您需要一个的 DataGrid 中显示表格数据,但要维护一个精确和交错对象关系图模型中。

应用程序服务也可相当用于集成多个模型是例如策略审核和核心策略工作流之间进行转换。 同样,我使用它们来引入组合的基础结构的依赖项。 假设要公开您的域模型,Windows Communication Foundation (WCF) 的常见方案。 我想使用应用程序服务修饰与 WCF 属性可这发生而不是我纯域模型允许 WCF 泄漏。

应用程序服务往往非常广泛且简略,体现为内聚性的功能。 请考虑接口和部分实现您在 图 4 中代码中看到作为应用程序服务的一个好示例。

图 4 A 简单应用程序服务

public IPolicyService {
  void Renew(PolicyRenewalDTO renewal);
  void Terminate(PolicyTerminationDTO termination);
  void Write(QuoteDTO quote);
}

public PolicyService : Service {
  private readonly ILogger _logger;
  public PolicyService(ILogger logger, IPolicyRepository policies) {
    _logger = logger;
    _policies = policies;
  }

  public void Renew(PolicyRenewalDTO renewal) {
    var policy = _policies.Find(renewal.PolicyID);
    policy.Renew();
    var logMessage = string.Format(
      "Policy {0} was successfully renewed by {1}.", 
      Policy.Number, renewal.RequestedBy);
    _logger.Log(logMessage);
  }
}

存储库保存并 Dispense 聚合的根目录

在您转到检索实体? 您如何存储它们? 存储库模式解答了这些问题。 储存库表示一个内存中集合,并传统智慧是得到了聚合的根每一个存储库。

储存库是一个很好候选一个超类或内容 Martin Fowler 引用为图层的父类型图案。 使用泛型一个基本的存储库接口派生前面的示例是一个简单的问题:

public interface IRepository<T>
  where T : IEntity
{
  Find<T>(int id);
  Find<T>(Query<T> query);
  Save(T entity);
  Delete(T entity);
}

储存库防止数据库或持久性概念,如 SQL 语句或与您的模型 commingling 和明显您手头的任务中的存储的过程: 捕获域。 这种模型代码分离从基础结构是一个很好的属性。 请参阅侧栏"anti-corruption 层"有关详细的讨论。

到目前为止您注意可能到我正在不讨论如何聚合根,其从属的实体,并且附加的值对象实际获取保留到磁盘。 这是有意的。 保存在您的模型中执行问题所需的数据是正交到自身模型问题。 持久性是基础结构。

这些技术的调查远远超出了范围的 DDD 简介。 可以地说很适用于和成熟的选项,用于存储您的模型数据从对象关系映射 (ORM) 框架不是简单的情况下的"汇总您的拥有"数据 mappers 文档面向数据库的多。

DDD 资源

官方 DDD 站点

How to 结构用户 Stories Dan North

The 大 ball 的 Mud 体系结构的样式

在 CodeBetter Greg 年轻人博客

Robert C。 在单个的责任主体 Martin 的纸张

在法则 Demeter brad Appleton

Martin Fowler 描述层类型模式

Robert C。 在该 S.O.L.I.D.Martin 原则

数据库的内容

通过这一点我肯定您已经认为"这是的确不错,Dave。 但在保存我的实体?" 是,您必须处理该重要的细节,但如何或在您保存您的模型很 tangential 到 DDD 的概述。

许多开发人员或数据库管理员将该数据库是模型的声明。 案例的一批次中如此部分。 数据库,高度标准化和使用一个图表制作的工具的可视化时可以传递了许多有关信息与您的域中的关系。

数据建模作为主要技术使操作需要,但是。 当您希望了解在同一个域只显示数据的技术 (如实体关系图 (ERDs) 或实体关系模型中固有行为,并且类关系图分解。 要查看在动作和如何类型要获取的协作工作完成的应用程序的部分。

我正在建模时我经常访问的白板上的序列图作为一种通信工具。 此方法将捕获大部分通信一个行为的设计或不统一建模语言 (UML) 或模型驱动体系结构的仪式的问题的实质。 我要避免不必要的仪式,尤其是在我要擦除我将放在白板的图表时。 我不要担心将 100%preferring 简单框、 下箭头和我可以快速完成的游泳泳道我关系图中的 UML 遵循。

如果已经不使用序列图团队,我将强烈建议学习该技术。 我所观察强大影响它们对周围 SRP,分层的体系结构对数据的行为设计通过问题中获得想的团队成员建模,和体系结构考虑一般情况下。

Getting Started with DDD

成为 proficient 与对象的面向编程是没有简单的任务。 我相信采用它、 簿的学习和实践,做法和更多的实践内, reach 的大多数专业开发人员,但它是生效。 它还有助于如果采用 craftsmanship 和连续的学习的态度。

您如何开始? 简单地说: 执行您的家庭作业。 了解等, S.O.L.I.D. 原则并研究 Eric Evans 的简介册。 您的时间投资将多个组成为其自身。 InfoQ 已生成 DDD 书介绍几个关键概念的一个较小版本。 如果您在财务或临时预算或只是调查模式下,建议没有启动。 一旦您获得可靠的 footing,wander 上以在 Yahoo! DDD 组 要查看问题在其他设计人员与努力和获取对话中。

DDD 不是新 doctrine 或方法。 很 time-tested 策略的集合。 当您准备进行练习时,尝试调整这些理念、 技术和在您的情况下,大多数有用的模式。 DDD 的一些元素比其他更普遍适用。 由 uncovering 以及使用无处不语言和标识我们正在建模的上下文中了解您的核心域存在的原因是比 nailing,完全不透明和 one-size-fits-all 存储库的很方式更重要的。

您在设计解决方案时设计的值。 如果设计器生成画并且开发人员设计器的一种,我们媒体将必须为商业价值。 值 consciousness trumps 注意事项,如遵循 dogma 和的同样重要,因为这些选择有时似乎的持久性技术的选择。

Dave Laribee coaches VersionOne 在产品开发团队。 他在本地和国家 / 地区的开发人员事件中发表演讲,并被授予一个 Microsoft 体系结构 MVP 2007 和 2008。 他在 CodeBetter 博客网络写入 thebeelog.com.