`

浅谈“领域驱动设计”

    博客分类:
  • DDD
阅读更多
Eric Evans所著的《领域驱动设计》(Domain-Driven Design:通常简称为“DDD”)一书可以说是经典中的经典,虽然“领域”的概念早就存在,但是直到这本书的出现,才让人们真正开始认真审视软件的构建,相信你看了这本书后会真正体会领域的力量,也正是这个力量决定了软件最终的价值。

领域的含义:

简单的说,每个软件程序都会与其用户的活动或兴趣相关,其中使用程序的主要环境称为软件的“领域”。

领域中形形色色的业务逻辑构成了软件丰富多采的行为。举例来说,银行财务系统中,领域逻辑就包括了诸如开户,转帐等等操作。可能你会说,PHP程序员很少会接触银行系统,这样的例子不够浅显,那我举一个更常见的例子,大凡程序员应该都接触过文章管理系统,它里面的置顶,加精等操作就是领域逻辑。这样看来,似乎用例对应的动作都是领域逻辑了,但是答案是否定了,比如说,文章管理系统中保存文章往往就不是领域逻辑,因为它只是一个和持久化相关的动作而已,是纯粹的技术实现,但是银行财务系统中的保存现金通常却被划为领域逻辑,因为它就是我们常说的存款,有明确的业务含义。看到这,似乎大家又有些Faint了,这里给出一个判断是否是领域逻辑的原则:就是这个逻辑动作是否有明确的业务上的含义,或者说是否是业务相关的,而不仅仅是技术相关的。

只有将技术实现手段从领域问题中剥离才能保证领域本身的精炼,保证程序员可以把精力集中到领域问题本身上来,而不会满脑子都是技术实现手段。

领域的组成:

按照Eric的表述,通常将领域中的组成角色分为以下五种:

实体(Entity):拥有唯一标识的对象。
值对象(Value Object):没有唯一标识的对象。
工厂(Factory):定义创建实体的方法。
仓储(Repository):管理实体的集合并封装其持久化过程。
服务(Service):实现不能指派或封装在一个单一对象上的操作。

领域的思考:

下面针对上面介绍的五种领域角色来逐一讨论。

实体的概念是比较好理解的,这样的例子很多,比如说每一个人都可以看作是一个“与众不同”的实体,我之所以用与众不同这个词是为了强调实体必须是能够唯一标识出来的,即便是在我们看作长得一模一样的双胞胎,他们也是能更根据一些标识来区分开,比如指纹,可能你会抬杠,要是没有手的残疾人怎么办?那样我们还可以使用DNA检测,当然,这些都是笑谈了,实际编程的时候,一般是使用一个自增数来作为标识,比如在MySQL数据库中保存实体的时候可以使用anto_increment属性的自增字段。需要注意的是如果想判断两个实体是否相等,不能根据实体的属性来判断,必须绝对依赖实体的标识,十年前的你和现在的你虽然在身高,体重,年龄等众多重要的属性中多或多或少的发生了变化,但你还是你,因为你的DNA不会因为这些属性的变化而变化。这些理解起来似乎有些哲学的味道了。

值对象的含义,老实说相对实体来说比较模糊,很多人喜欢把数据传输对象也称为值对象(数据传输对象和我们这里说的值对象是有差别的)让人们对值对象的理解产生过很多歧义,而且值对象的例子不如实体那么直接。从字面上来理解,值对象没有唯一标识,大多数情况下,值对象是不变的,所以系统不用实时的跟踪他们,用的时候就实例化一个,不用的时候就销毁,但是,什么时候使用值对象?把哪些属性划为值对象?值对象的作用是什么?这些都是值得考虑的问题。通常来说,当我们进行领域建模的时候,优先把唯一标识和经常用来检索对象的信息作为实体的属性,而其他信息根据相关性或者划分到其他实体中,或者划分为值对象,举例来说:一个CMS系统中,对于文章实体而言,文章编号,文章标题等都应该作为文章实体的属性存在,而对于文章有效性期限的开始时间,结束时间两个信息则应该被放在一个独立的值对象中,这其中,只有开始时间或结束时间,或者开始时间和结束时间同时都存在或不存在,会代表不同的逻辑意义,合理使用值对象,既有利于屏蔽一些相关逻辑的复杂性,也可以保持实体对象的简洁。

工厂相对与前两者会好理解的多,毕竟从名字上就能体现出它的职责,那就是创建对象。既然是创建对象,那我们直接实例化一个不行么?简单的情况是可以的,但是工厂往往会带来巨大的好处,简单的说就是屏蔽了创建对象的复杂性。领域创建对象强调的关联,一组相关的对象应该被看作一个整体,对于其中任何对象的访问也应该从这个整体的“根”开始(通常整体中最重要的实体作为跟),所以复杂的关联必然会使创建过程同样复杂起来,那我们可不可以在“根”实体的构造函数中完成对象的组装呢,简单的情况可以,复杂的不合适,比如说组装汽车,通常是在工厂里由组装工人和机器人来操作完成,如果我们在“跟”的构造函数里完成组装,无异与在汽车里配备了组装工人和机器人,这当然是不必要的,汽车一旦组装出厂,就不需要组装工人和机器人了,此时再附带他们是一种累赘。

仓储的概念和一些人常说的数据访问对象(DAO)有些类似,但是并不等同,二者一个很大的不同是仓储有“根”的概念,而数据访问对象往往是按照数据库的表来划分的。使用仓储主要是为了查询和持久化领域对象,而领域对象之间往往会有复杂的聚合关系,为了保证不变量,所以才引入根的概念,对领域对象中某个子对象的访问必须通过根来导航。这样说可能不易理解,我举一个简单的例子:轿车,轮胎可以看成是一个领域对象的聚合,轿车是这个聚合的根,如果我们想访问轮胎,必须通过轿车的导航来进行,为什么如此规定,因为轿车和轮胎之间存在一个不变量:一个轿车有四个轮胎,如果允许客户端直接访问轮胎,那么就很难保证此逻辑不被破坏。

服务这个名词被用过很多次了,但是以前人们说的服务大多是从技术角度而言的,从分层来看属于应用层。一般是诸如注册成功发送一个邮件之类的东西,领域驱动设计中的服务不是这个范畴的概念,它强调的是实体之间的相互关系,而不是纯粹意义上的技术手段。举一个例子来说:CMS系统里,如果一篇文章被加入精华,则文章作者的经验值加一。此逻辑中涉及量个实体:文章实体和作者实体。经验值加一的逻辑不管是建立在文章实体里,还是作者实体里都显得冗余,所以有必要在实体之上在抽象出一个服务层来处理。这里可能有人会问:这样的逻辑我们放到传统意义上的应用层不行么?那样做不能说不行,但是多数情况不好,因为此逻辑属于领域逻辑,而不是应用逻辑,如果放在应用层,领域逻辑就外泄了,领域层也就成为了摆设,但是也有例外,有时候我们可能一时很难分辨一个逻辑是领域逻辑还是应用逻辑,这个时候把此逻辑加入到应用层是没有问题的,如果以后发现其作为领域逻辑更合适的话再重构不迟。

分享到:
评论

相关推荐

    浅谈我对DDD领域驱动设计的理解 – 码农网1

    领域驱动设计(DDD)是一种软件开发方法,它强调以业务领域为中心进行系统设计,通过创建领域模型来理解和解决复杂业务问题。DDD的核心理念是将业务逻辑转化为可执行的代码,从而确保软件系统能够准确地反映业务需求...

    浅谈LED驱动设计思想

    LED在可携式产品中背光源的地位已经不可动摇,即便是在大尺寸LCD的背光源当中,...驱动电路是LED(发光二极体)产品的重要组成部分,无论在照明、背光源还是显示板领域,驱动电路技术架构的选择都应与具体的应用相匹配。

    浅谈我对DDD领域驱动设计的理解

    当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决。比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品。...

    浅谈LED线性驱动和开关型驱动

    例如,在一些小型照明设备或装饰灯具中,线性驱动因其简单的设计而被广泛应用。 #### 三、开关型驱动 开关型驱动是一种更为高效的LED驱动方式,它通过控制开关元件(如MOSFET)的导通和截止状态来实现电流调节。...

    浅谈电机与驱动器的同步测量

    本文将浅谈电机与驱动器的同步测量的重要性与实践方法,以及它在电机性能评估和优化中的关键作用。 首先,我们需要明确的是电机与驱动器同步测量的目的。简单来说,就是为了让电机在不同的工作状态下与驱动器保持...

    浅谈人工智能驱动的人文社会科学研究转型.zip

    标题中的“浅谈人工智能驱动的人文社会科学研究转型”揭示了本次讨论的核心——人工智能(AI)在人文社会科学领域的应用及其带来的变革。这篇论文或报告可能深入分析了AI如何改变研究方法、数据分析、理论构建以及...

    浅谈电力驱动系统电气工程与自动化控制的PLC应用技术.pdf

    电力驱动系统电气工程与自动化控制是现代工业和交通运输领域中不可或缺的一部分。随着技术的不断进步,对电力驱动系统的要求也越来越高,尤其在自动化控制方面,PLC(Programmable Logic Controller)技术的应用已...

    浅谈领域模型

    领域模型是什么?...很多人一上来理解领域驱动设计(DDD),基本都是一头雾水,因为模型设计的初衷并不是围绕性能、架构、分层等软件概念展开的,而是从边界、内聚等抽象概念开始讲起。理解领域模型,并不是通过

    FPGA设计工具浅谈.pdf

    【FPGA设计工具浅谈】 FPGA(Field-Programmable Gate Array)作为一种可编程逻辑器件,因其灵活性和高性能在电子系统设计中扮演着日益重要的角色。随着技术的进步,FPGA不仅可作为协处理器和DSP引擎,甚至可以作为...

    浅谈人工智能机器人的保险设计——以手术机器人为例.pdf

    而且,手术机器人通常是电力驱动,如果散热不及时,可能会导致电池寿命减少,甚至自燃引发爆炸等严重后果。因此,通过设计合适的保险产品可以为这些潜在风险提供保障。 其次,医疗事故责任的判定也是保险设计中的...

    浅谈提高机械设计制造及其自动化的有效途径 (2).pdf

    文章《浅谈提高机械设计制造及其自动化的有效途径》通过对自动化技术的深入分析,探讨了提高机械设计制造自动化水平的有效方法,并指出了当前机械设计制造及其自动化的发展现状和未来趋势。 一、自动化技术在机械...

    浅谈复杂业务系统的架构设计

    同样地,在软件开发领域中,诸如领域驱动设计(DDD)、模型视图控制器(MVC)等模式也被视为特定领域的架构设计。 ### 三、架构的本质 架构的概念最初源自建筑行业,指代建筑物的设计和构造过程。将这一概念应用于...

    浅谈汽车行业的分类.pptx

    首先,汽车被定义为由动力驱动,有四个或以上车轮,非轨道承载的车辆。汽车行业的核心部分主要包括整车、汽车零部件和其他相关服务。在整车领域,汽车被分为两大类:乘用车和商用车。 乘用车是主要针对个人或家庭...

    220v接光耦驱动继电器原理图 浅谈光耦驱动电路.zip-综合文档

    综上所述,220V光耦驱动继电器电路是电力控制和自动化领域的一种常见解决方案,通过光耦的隔离作用,确保了控制系统的安全性和可靠性。了解并掌握这种电路的设计原理和实践技巧,对于提升电子工程师的技能水平至关...

Global site tag (gtag.js) - Google Analytics