DDD领域驱动
领域驱动设计(DDD)作为一种软件开发方法,它可以帮助我们设计高质量的软件模型。在正确实现的情况下,我们通过DDD完成的设计恰恰就是软件的工作方式。
什么是领域模型?
领域模型是关于某个特定业务领域的软件模型。通常,领域模型通过对象模型来实现,这些对象同时包含了数据和行为,并且表达了准确的业务含义。
处理领域复杂性
在使用DDD时,我们首先希望将它应用在最重要的业务场景下。对于那些可以轻易替换的软件来说,你是不会有所投入的。相反,值得你投入的是那些重要的、复杂的东西,因为这些东西将为你带来可观的回报。正因如此,我们将这样的模型命名为核心域(Core Domain),而那些相对次要的称为支撑子域(Supporting Subdomain)。那么现在,我们需要搞明白的是,“复杂”到底是什么意思?
DDD的作用是简化,而不是复杂化。
在使用DDD时,我们应该采用最简单的方式对复杂领域进行建模,而不是使问题变得更加复杂。
不同的业务领域对于复杂的定义是不一样的。另外,不同的公司所面临的挑战是不一样的;成熟度不一样;软件开发能力也不一样。因此,与其去定义什么是复杂的,还不如定义什么是重要的。这时,你的团队和管理层应该做出决定:你们开发的软件系统是否值得做出DDD投入。
贫血领域对象
领域对象当中只有getter和setter方法,并且几乎没有业务逻辑。
贫血领域对象是不好的,因为你花了很大的成本来开发领域对象,但是从中获益甚少。比如,由于存在对象-关系阻抗失配,开发者需要将很多时间花在对象和数据存储之间的映射上。这样的代价太大,而受益太小。我得说,你所说的领域对象根本就不是领域对象,而只是将关系型数据库中的模型映射到对象上而已。这样的领域对象更像是活动记录,此时你可以对架构做个简化,然后使用事物脚本进行开发。
贫血领域对象反应了一种自然的过程式的编码风格,但我并不认为这是首要原因。我们很多开发者都是学者示例代码做开发的这并不是什么坏事,只要示例代码本身是好的。然而,通常情况是,实例代码只是用尽可能简单的方式来展示某个特定的概念或者API特性,而并不是要强调遵循好多的设计原则。一些极度简化的示例代码总是包含了大量的getter和setter,于是这些getter和setter随着示例代码每天被程序员们原封不动的来回复制。
如何DDD
通用语言
通用语言是团队共享的语言。领域专家和开发者使用的相同的语言进行交流。事实上,团队中每个人都是用相同的通用语言。不管你在团队中的角色如何,只要你是团队的一员,你都将使用通用语言。
使用DDD的业务价值
(1)你获得了一个非常有用的领域模型
(2)你的业务得到了更准确的定义和理解
(3)领域专家可以为软件设计做出贡献
(4)更好的用户体验
(5)清晰的模型边界
(6)更好的企业架构
(7)敏捷、迭代和持续建模
(8)使用战略和战术新工具
直接上代码,使用属性访问:
service代码如下:
使用领域对象的行为,这种行为表达出了领域中的通用语言:
此时service代码如下:
领域
领域(Domain)即是一个组织所做的事情以及其中所包含的一切。商业机构通常会确定一个市场,然后在这个市场中销售产品和服务。每个组织都有它自己的业务范围和做事方式。这个业务范围以及在其中所进行的活动便是领域。当你为某个组织开发软件的时,你面对的便是这个组织的领域。这个领域对于你来说应该是明晰的,以为你在这个领域中工作。
有一点需要注意的是,“领域”这个词可能承载了太多含义。领域既可以表示整个业务系统,也可以表示其中某个核心领域或者支撑子域。
由于“领域模型”包含了“领域”这个词,我们可能会认为应该为整个业务系统创建一个单一的、内聚的、全功能式的模型。然而,这并不是我们使用DDD的目标。正好相反,在DDD中,一个领域被分为若干子域,领域模型在限界上下文中完成开发。事实上,在开发一个领域模型时,我们关注的通常只是这个业务系统的某个方面。试图创建一个全功能的领域模型好似非常困难的,并且容易导致失败。既然领域模型不能包含整个业务系统,我们应该如何来划分领域模型呢?那就时将这些功能分开对待。
子域并不是一定要做得很大,并且包含很多功能。有时,子域可以简单到只包含一套算法,这套算法可能对于业务系统来说非常重要,但是并不包含在核心领域之中。在正确实施DDD的情况下,这种简单的子域可以以模块的形式从核心域中分离出来,而不需要包含在笨重的子系统组件中。
未完待续。。。
领取专属 10元无门槛券
私享最新 技术干货