业务初期,我们的功能大都非常大略,普通的CRUD就能知足,此时系统是清晰的。随着迭代的不断蜕变,业务逻辑变得越来越繁芜,我们的系统也越来越冗杂。模块彼此关联,谁都很难说清模块的详细功能意图是啥。修正一个功能时,每每光回溯该功能须要的修正点就须要很永劫光,更别提修正带来的不可预知的影响面。
下图是一个常见的系统耦合病例。
订单做事接口中供应了查询、创建订单干系的接口,也供应了订单评价、支付、保险的接口。同时我们的表也是一个订单大表,包含了非常多字段。在我们掩护代码时,牵一发而动全身,很可能只是想改下评价干系的功能,却影响到了创单核心路径。虽然我们可以通过测试担保功能完备性,但当我们在订单领域有大量需求同时并行开拓时,改动重叠、恶性循环、疲于奔命修正各种问题。

上述问题,归根到底在于系统架构不清晰,划分出来的模块内聚度低、高耦合。
有一种办理方案,按照演进式设计的理论,让系统的设计随着系统实现的增长而增长。我们不须要作提前设计,就让系统伴随业务发展而演进。这当然是可行的,敏捷实践中的重构、测试驱动设计及持续集成可以对付各种混乱问题。重构——保持行为不变的代码改进打消了不折衷的局部设计,测试驱动设计确保对系统的变动不会导致系统丢失或毁坏现有功能,持续集成则为团队供应了同一代码库。
在这三种实践中,重构是战胜演进式设计中大杂烩问题的主力,通过在单独的类及方法级别上做一系列小步重构来完成。我们可以很随意马虎重构出一个独立的类来放某些通用的逻辑,但是你会创造你很难给它一个业务上的含义,只能给予一个技能维度描述的含义。这会带来什么问题呢?新同学并不总是知道对通用逻辑的改动或获取来自该类。显然,制订项目规范并不是好的idea。我们又闻到了代码即将腐败的味道。
事实上,你可能意识到问题之所在。在办理现实问题时,我们会将问题映射到脑海中的观点模型,在模型中办理问题,再将办理方案转换为实际的代码。上述问题在于我们办理了设计到代码之间的重构,但提炼出来的设计模型,并不具有实际的业务含义,这就导致在开拓新需求时,其他同学并不能很自然地将业务问题映射到该设计模型。设计彷佛变成了重构者的自娱自乐,代码连续腐败,重新重构……无休止的循环。
用DDD则可以很好地办理领域模型到设计模型的同步、蜕变,末了再将反响了领域的设计模型转为实际的代码。
注:模型是我们办理实际问题所抽象出来的观点模型,领域模型则表达与业务干系的事实;设计模型则描述了所要构建的系统。
血虚症和失落忆症
血虚领域工具
血虚领域工具(Anemic Domain Object)是指仅用作数据载体,而没有行为和动作的领域工具。
在我们习气了J2EE的开拓模式后,Action/Service/DAO这种分层模式,会很自然地写出过程式代码,而学到的很多关于OO理论的也毫无用武之地。利用这种开拓办法,工具只是数据的载体,没有行为。以数据为中央,以数据库ER设计作驱动。分层架构在这种开拓模式下,可以理解为是对数据移动、处理和实现的过程。
以笔者最近开拓的系统抽奖平台为例:
场景需求奖池里配置了很多奖项,我们须要按运营预先配置的概率抽中一个奖项。实现非常大略,天生一个随机数,匹配符合该随机数天生概率的奖项即可。血虚模型实现方案先设计奖池和奖项的库表配置。设计AwardPool和Award两个工具,只有大略的get和set属性的方法Service代码实现设计一个LotteryService,在个中的drawLottery()方法写做事逻辑
按照我们常日思路实现,可以创造:在业务领域里非常主要的抽奖,我的业务逻辑都是写在Service中的,Award充其量只是个数据载体,没有任何行为。大略的业务系统采取这种血虚模型和过程化设计是没有问题的,但在业务逻辑繁芜了,业务逻辑、状态会散落到在大量方法中,原来的代码意图会逐渐不明确,我们将这种情形称为由血虚症引起的失落忆症。
更好的是采取领域模型的开拓办法,将数据和行为封装在一起,并与现实天下中的业务工具相映射。各种具备明确的职责划分,将领域逻辑分散到领域工具中。连续举我们上述抽奖的例子,利用概率选择对应的奖品就应该放到AwardPool类中。
为什么选择DDD软件系统繁芜性应对
办理繁芜和大规模软件的武器可以被粗略地归为三类:抽象、分治和知识。
分治 把问题空间分割为规模更小且易于处理的多少子问题。分割后的问题须要足够小,以便一个人单枪匹马就能够办理他们;其次,必须考虑如何将分割后的各个部分装置为整体。分割得越合理越易于理解,在装置成整体时,所需跟踪的细节也就越少。即更随意马虎设计各部分的协作办法。评判什么是分治得好,即高内聚低耦合。
抽象 利用抽象能够精简问题空间,而且问题越小越随意马虎理解。举个例子,从北京到上海出差,可以先理解为利用交通工具前往,但不须要一开始就想清楚到底是高铁还是飞机,以及乘坐它们须要把稳什么。
知识 顾名思义,DDD可以认为是知识的一种。
DDD供应了这样的知识手段,让我们知道如何抽象出限界高下文以及如何去分治。
与微做事架构相得益彰
微做事架构众所周知,此处不做赘述。我们创建微做事时,须要创建一个高内聚、低耦合的微做事。而DDD中的限界高下文则完美匹配微做事哀求,可以将该限界高下文理解为一个微做事进程。
上述是从更直不雅观的角度来描述两者的相似处。
在系统繁芜之后,我们都须要用分治来拆解问题。一样平常有两种办法,技能维度和业务维度。技能维度是类似MVC这样,业务维度则是指按业务领域来划分系统。
微做事架构更强调从业务维度去做分治来应对系统繁芜度,而DDD也是同样的着重业务视角。
如果两者在追求的目标(业务维度)达到了高下文的统一,那么在详细做法上有什么联系和不同呢?
我们将架构设计活动精简为以下三个层面:
业务架构——根据业务需求设计业务模块及其关系系统架构——设计系统和子系统的模块技能架构——决定采取的技能及框架以上三种活动在实际开拓中是有先后顺序的,但不一定孰先孰后。在我们办理常规套路问题时,我们会很自然地往熟习的分层架构套(先确定系统架构),或者用PHP开拓很快(先确定技能架构),在业务不繁芜时,这样是合理的。
跳过业务架构设计出来的架构关注点不在业务相应上,可能便是个大泥球,在面临需求迭代或相应市场变革时就很痛楚。
DDD的核心诉求便是将业务架构映射到系统架构上,在相应业务变革调度业务架构时,也随之变革系统架构。而微做事追求业务层面的复用,设计出来的系统架构和业务同等;在技能架构上则系统模块之间充分解耦,可以自由地选择得当的技能架构,去中央化地管理技能和数据。
可以拜会下图来更好地理解双方之间的协作关系:
如何实践DDD我们将通过上文提到的抽奖平台,来详细先容我们如何通过DDD来解构一个中型的基于微做事架构的系统,从而做到系统的高内聚、低耦合。
首先看下抽奖系统的大致需求:
运营——可以配置一个抽奖活动,该活动面向一个特定的用户群体,并针对一个用户群体发放一批不同类型的奖品(优惠券,激活码,实物奖品等)。
用户——通过活动页面参与不同类型的抽奖活动。
设计领域模型的一样平常步骤如下:
根据需求划分出初步的领域和限界高下文,以及高下文之间的关系;进一步剖析每个高下文内部,识别出哪些是实体,哪些是值工具;对实体、值工具进行关联和聚合,划分出聚合的范畴和聚合根;为聚合根设计仓储,并思考实体或值工具的创建办法;在工程中实践领域模型,并在实践中考验模型的合理性,倒推模型中不敷的地方并重构。计策建模
计策和战术设计是站在DDD的角度进行划分。计策设计侧重于高层次、宏不雅观上去划分和集成限界高下文,而战术设计则关注更详细利用建模工具来细化高下文。
领域
现实天下中,领域包含了问题域和解系统。一样平常认为软件是对现实天下的部分仿照。在DDD中,解系统可以映射为一个个限界高下文,限界高下文便是软件对付问题域的一个特定的、有限的办理方案。
限界高下文
一个由显式边界限定的特定职责。领域模型便存在于这个边界之内。在边界内,每一个模型观点,包括它的属性和操作,都具有分外的含义。
一个给定的业务领域会包含多个限界高下文,想与一个限界高下文沟通,则须要通过显式边界进行通信。系统通过确定的限界高下文来进行解耦,而每一个高下文内部紧密组织,职责明确,具有较高的内聚性。
一个很形象的隐喻:细胞质以是能够存在,是由于细胞膜限定了什么在细胞内,什么在细胞外,并且确定了什么物质可以通过细胞膜。
划分限界高下文
划分限界高下文,不管是Eric Evans还是Vaughn Vernon,在他们的大作里都没有怎么提及。
显然我们不应该按技能架构或者开拓任务来创建限界高下文,该当按照语义的边界来考虑。
我们的实践是,考虑产品所讲的通用措辞,从中提取一些术语称之为观点工具,探求工具之间的联系;或者从需求里提取一些动词,不雅观察动词和工具之间的关系;我们将紧耦合的各自圈在一起,不雅观察他们内在的联系,从而形成对应的限界高下文。形成之后,我们可以考试测验用措辞来描述下限界高下文的职责,看它是否清晰、准确、简洁和完全。简言之,限界高下文该当从需求出发,按领域划分。
前文提到,我们的用户划分为运营和用户。个中,运营对抽奖活动的配置十分繁芜但相对低频。用户对这些抽奖活动配置的利用是高频次且无感知的。根据这样的业务特点,我们首先将抽奖平台划分为C端抽奖和M端抽奖管理平台两个子域,让两者完备解耦。
在确认了M端领域和C真个限界高下文后,我们再对各自高下文内部进行限界高下文的划分。下面我们用C端进行举例。
产品的需求概述如下:
1. 抽奖活动有活动限定,例如用户的抽奖次数限定,抽奖的开始和结束的韶光等;
2. 一个抽奖活动包含多个奖品,可以针对一个或多个用户群体;
3. 奖品有自身的奖品配置,例如库存量,被抽中的概率等,最多被一个用户抽中的次数等等;
4. 用户群体有多种差异办法,如按照用户所在城市区分,按照新老客区分等;
5. 活动具有风控配置,能够限定用户参与抽奖的频率。
根据产品的需求,我们提取了一些关键性的观点作为子域,形成我们的限界高下文。
首先,抽奖高下文作为全体领域的核心,承担着用户抽奖的核心业务,抽奖中包含了奖品和用户群体的观点。
在设计初期,我们曾经考虑划分出抽奖和发奖两个领域,前者卖力选奖,后者卖力将选中的奖品发放出去。但在实际开拓过程中,我们创造这两部分的逻辑紧密连接,难以拆分。并且纯挚的发奖逻辑足够大略,仅仅是调用第三方做事进行发奖,不敷以独立出来成为一个领域。对付活动的限定,我们定义了活动准入的通用措辞,将活动开始/结束韶光,活动可参与次数等限定条件都收拢到活动准入高下文中。
对付抽奖的奖品库存量,由于库存的行为与奖品本身相对解耦,库存关注点更多是库存内容的核销,且库存本身具备通用性,可以被奖品之外的内容利用,因此我们定义了独立的库存高下文。
由于C端存在一些刷单行为,我们根据产品需求定义了风控高下文,用于对活动进行风控。
末了,活动准入、风控、抽奖等领域都涉及到一些次数的限定,因此我们定义了计数高下文。
可以看到,通过DDD的限界高下文划分,我们界定出抽奖、活动准入、风控、计数、库存等五个高下文,每个高下文在系统中都高度内聚。
高下文映射图
在进行高下文划分之后,我们还须要进一步梳理高下文之间的关系。
康威(梅尔·康威)定律
任何组织在设计一套系统(广义观点上的系统)时,所交付的设计方案在构造上都与该组织的沟通构造保持同等。
康威定律见告我们,系统构造应只管即便的与组织构造保持同等。这里,我们认为团队构造(无论是内部组织还是团队间组织)便是组织构造,限界高下文便是系统的业务构造。因此,团队构造该当和限界高下文保持同等。
梳理清楚高下文之间的关系,从团队内部的关系来看,有如下好处:
任务更好拆分,一个开拓职员可以全身心的投入到干系的一个单独的高下文中;沟通更加顺畅,一个高下文可以明确自己对其他高下文的依赖关系,从而使得团队内开拓直接更好的对接。从团队间的关系来看,明确的高下文关系能够带来如下帮助:
每个团队在它的高下文中能够更加明确自己领域内的观点,由于高下文是领域的解系统;对付限界高下文之间发生交互,团队与高下文的同等性,能够担保我们明确对接的团队和依赖的高下游。限界高下文之间的映射关系
互助关系(Partnership):两个高下文紧密互助的关系,一荣俱荣,一损俱损。共享内核(Shared Kernel):两个高下文依赖部分共享的模型。客户方-供应方开拓(Customer-Supplier Development):高下文之间有组织的高下游依赖。遵奉者(Conformist):下贱高下文只能盲目依赖上游高下文。防腐层(Anticorruption Layer):一个高下文通过一些适配和转换与另一个高下文交互。开放主机做事(Open Host Service):定义一种协议来让其他高下文来对本高下文进行访问。发布措辞(Published Language):常日与OHS一起利用,用于定义开放主机的协议。大泥球(Big Ball of Mud):殽杂在一起的高下文关系,边界不清晰。另谋他路(Separate Way):两个完备没有任何联系的高下文。上定亲义了高下文映射间的关系,经由我们的反复推敲,抽奖平台高下文的映射关系图如下:
由于抽奖,风控,活动准入,库存,计数五个高下文都处在抽奖领域的内部,以是它们之间符合“一荣俱荣,一损俱损”的互助关系(PartnerShip,简称PS)。
同时,抽奖高下文在进行发券动作时,会依赖券码、平台券、外卖券三个高下文。抽奖高下文通过防腐层(Anticorruption Layer,ACL)对三个高下文进行了隔离,而三个券高下文通过开放主机做事(Open Host Service)作为发布措辞(Published Language)对抽奖高下文供应访问机制。
通过高下文映射关系,我们明确的限定了限界高下文的耦合性,即在抽奖平台中,无论是高下文内部交互(互助关系)还是与外部高下文交互(防腐层),耦合度都限定在数据耦合(Data Coupling)的层级。
战术建模——细化高下文
梳理清楚高下文之间的关系后,我们须要从战术层面上阐发高下文内部的组织关系。首先看下DDD中的一些定义。
实体
当一个工具由其标识(而不是属性)区分时,这种工具称为实体(Entity)。
例:最大略的,公安系统的身份信息录入,对付人的仿照,即认为是实体,由于每个人是独一无二的,且其具有唯一标识(如公安系统分发的身份证号码)。
在实践上建议将属性的验证放到实体中。
值工具
当一个工具用于对事务进行描述而没有唯一标识时,它被称作值工具(Value Object)。
例:比如颜色信息,我们只须要知道{\公众name\公众:\公众玄色\"大众,\公众css\"大众:\"大众#000000\"大众}这样的值信息就能够知足哀求了,这避免了我们对标识追踪带来的系统繁芜性。
值工具很主要,在习气了利用数据库的数据建模后,很随意马虎将所有工具看作实体。利用值工具,可以更好地做系统优化、精简设计。
它具有不变性、相等性和可更换性。
在实践中,须要担保值工具创建后就不能被修正,即不许可外部再修正其属性。在不同高下文集成时,会涌现模型观点的公用,如商品模型会存在于电商的各个高下文中。在订单高下文中如果你只关注下单时商品信息快照,那么将商品工具视为值工具是很好的选择。
聚合根
Aggregate(聚合)是一组干系工具的凑集,作为一个整体被外界访问,聚合根(Aggregate Root)是这个聚合的根节点。
聚合是一个非常主要的观点,核心领域每每都须要用聚合来表达。其次,聚合在技能上有非常高的代价,可以辅导详细设计。
聚合由根实体,值工具和实体组成。
如何创建好的聚合?
边界内的内容具有同等性:在一个事务中只修正一个聚合实例。如果你创造边界内很难接管强同等,不管是出于性能或产品需求的考虑,该当考虑剥离出独立的聚合,采取终极同等的办法。设计小聚合:大部分的聚合都可以只包含根实体,而无需包含其他实体。纵然一定要包含,可以考虑将其创建为值工具。通过唯一标识来引用其他聚合或实体:当存在工具之间的关联时,建议引用其唯一标识而非引用其整体工具。如果是外部高下文中的实体,引用其唯一标识或将须要的属性布局值工具。如果聚合创建繁芜,推举利用工厂方法来屏蔽内部繁芜的创建逻辑。聚合内部多个组成工具的关系可以用来辅导数据库创建,但不可避免存在一定的抗阻。如聚合中存在List<值工具>,那么在数据库中建立1:N的关联须要将值工具单独建表,此时是有id的,建议不要将该id暴露到资源库外部,对外暗藏。
领域做事
一些主要的领域行为或操作,可以归类为领域做事。它既不是实体,也不是值工具的范畴。
当我们采取了微做事架构风格,统统领域逻辑的对外暴露均须要通过领域做事来进行。如原来由聚合根暴露的业务逻辑也须要依托于领域做事。
领域事宜
领域事宜是对领域内发生的活动进行的建模。
抽奖平台的核心高下文是抽奖高下文,接下来先容下我们对抽奖高下文的建模。
在抽奖高下文中,我们通过抽奖(DrawLottery)这个聚合根来掌握抽奖行为,可以看到,一个抽奖包括了抽奖ID(LotteryId)以及多个奖池(AwardPool),而一个奖池针对一个特定的用户群体(UserGroup)设置了多个奖品(Award)。
其余,在抽奖领域中,我们还会利用抽奖结果(SendResult)作为输出信息,利用用户领奖记录(UserLotteryLog)作为领奖凭据和存根。
谨慎利用值工具
在实践中,我们创造虽然一些领域工具符合值工具的观点,但是随着业务的变动,很多原有的定义会发生变更,值工具可能须要在业务意义具有唯一标识,而对这类值工具的重构每每须要较高本钱。因此在特定的情形下,我们也要根据实际情形来权衡领域工具的选型。
DDD工程实现
在对高下文进行细化后,我们开始在工程中真正落地DDD。
模块
模块(Module)是DDD中明确提到的一种掌握限界高下文的手段,在我们的工程中,一样平常只管即便用一个模块来表示一个领域的限界高下文。
如代码中所示,一样平常的工程中包的组织办法为{com.公司名.组织架构.业务.高下文.},这样的组织构造能够明确的将一个高下文限定在包的内部。
代码演示1 模块的组织
对付模块内的组织构造,一样平常情形下我们是按照领域工具、领域做事、领域资源库、防腐层等组织办法定义的。
代码演示2 模块的组织
每个模块的详细实现,我们将不才文中展开。
领域工具
前文提到,领域驱动要办理的一个主要的问题,便是办理工具的血虚问题。这里我们用之前定义的抽奖(DrawLottery)聚合根和奖池(AwardPool)值工具来详细解释。
抽奖聚合根持有了抽奖活动的id和该活动下的所有可用奖池列表,它的一个最紧张的领域功能便是根据一个抽奖发生场景(DrawLotteryContext),选择出一个适配的奖池,即chooseAwardPool方法。
chooseAwardPool的逻辑是这样的:DrawLotteryContext会带有用户抽奖时的场景信息(抽奖得分或抽奖时所在的城市),DrawLottery会根据这个场景信息,匹配一个可以给用户发奖的AwardPool。
代码演示3 DrawLottery
在匹配到一个详细的奖池之后,须要确定末了给用户的奖品是什么。这部分的领域功能在AwardPool内。
代码演示4 AwardPool
与以往的仅有getter、setter的业务工具不同,领域工具具有了行为,工具更加丰满。同时,比起将这些逻辑写在做事内(例如Service),领域功能的内聚性更强,职责更加明确。
资源库
领域工具须要资源存储,存储的手段可以是多样化的,常见的无非是数据库,分布式缓存,本地缓存等。资源库(Repository)的浸染,便是对领域的存储和访问进行统一管理的工具。在抽奖平台中,我们是通过如下的办法组织资源库的。
代码演示5 Repository组织构造
资源库对外的整体访问由Repository供应,它聚合了各个资源库的数据信息,同时也承担了资源存储的逻辑(例如缓存更新机制等)。
在抽奖资源库中,我们屏蔽了对底层奖池和奖品的直接访问,而是仅对抽奖的聚合根进行资源管理。代码示例中展示了抽奖资源获取的方法(最常见的Cache Aside Pattern)。
比起以往将资源管理放在做事中的做法,由资源库对资源进行管理,职责更加明确,代码的可读性和可掩护性也更强。
代码演示6 DrawLotteryRepository
防腐层
亦称适配层。在一个高下文中,有时须要对外部高下文进行访问,常日会引入防腐层的观点来对外部高下文的访问进行一次转义。
有以下几种情形会考虑引入防腐层:
须要将外部高下文中的模型翻译本钱高下文理解的模型。不同高下文之间的团队协作关系,如果是供奉者关系,建议引入防腐层,避免外部高下文变革对本高下文的侵蚀。该访问本高下文利用广泛,为了避免改动影响范围过大。如果内部多个高下文对外部高下文须要访问,那么可以考虑将其放到通用高下文中。
在抽奖平台中,我们定义了用户城市信息防腐层(UserCityInfoFacade),用于外部的用户城市信息高下文(微做事架构下表现为用户城市信息做事)。
以用户信息防腐层举例,它以抽奖要求参数(LotteryContext)为入参,以城市信息(MtCityInfo)为输出
代码演示7 UserCityInfoFacade
领域做事
上文中,我们将领域行为封装到领域工具中,将资源管理行为封装到资源库中,将外部高下文的交互行为封装到防腐层中。此时,我们再回过分来看领域做事时,能够创造领域做事本身所承载的职责也就更加清晰了,即便是通过串联领域工具、资源库和防腐层等一系列领域内的工具的行为,对其他高下文供应交互的接口。
我们以抽奖做事为例(issueLottery),可以看到在省略了一些防御性逻辑(非常处理,空值判断等)后,领域做事的逻辑已经足够清晰明了。
代码演示8 LotteryService
数据流转
在抽奖平台的实践中,我们的数据流转如上图所示。
首先领域的开放做事通过信息传输工具(DTO)来完成与外界的数据交互;在领域内部,我们通过领域工具(DO)作为领域内部的数据和行为载体;在资源库内部,我们沿袭了原有的数据库持久化工具(PO)进行数据库资源的交互。同时,DTO与DO的转换发生在领域做事内,DO与PO的转换发生在资源库内。
与以往的业务做事比较,当前的编码规范可能多造成了一次数据转换,但每种数据工具职责明确,数据流转更加清晰。
高下文集成
常日集成高下文的手段有多种,常见的手段包括开放领域做事接口、开放HTTP做事以及发布-订阅机制。
在抽奖系统中,我们利用的是开放做事接口进行交互的。最明显的表示是计数高下文,它作为一个通用高下文,对抽奖、风控、活动准入等高下文都供应了访问接口。
同时,如果在一个高下文对另一个高下文进行集成时,若须要一定的隔离和适配,可以引入防腐层的观点。这一部分的示例可以参考前文的防腐层代码示例。
分离领域
接下来讲解在履行领域模型的过程中,如何运用到系统架构中。
我们采取的微做事架构风格,与Vernon在《实现领域驱动设计》并不太同等,更详细差异可阅读他的书体会。
如果我们掩护一个从前到后的运用系统:
下图中领域做事是利用微做事技能剥离开来,独立支配,对外暴露的只能是做事接口,领域对外暴露的业务逻辑只能依托于领域做事。而在Vernon著作中,并未假定微做事架构风格,因此领域层暴露的除了领域做事外,还有聚合、实体和值工具等。此时的运用做事层是比较大略的,获取来自接口层的要求参数,调度多个领域做事以实现界面层功能。
随着业务发展,业务系统快速膨胀,我们的系统属于核心时:
运用做事虽然没有领域逻辑,但涉及到了对多个领域做事的编排。当业务规模弘大到一定程度,编排本身就富含了业务逻辑(除此之外,运用做事在稳定性、性能上所做的方法也希望统一起来,而非散落各处),那么此时运用做事对付外部来说是一个领域做事,整体看起来则是一个独立的限界高下文。
此时运用做事对内还属于运用做事,对外已是领域做事的观点,须要将其暴露为微做事。
注:详细的架构实践可按照团队和业务的实际情形来,此处仅为作者自身的业务实践。除分层架构外,如CQRS架构也是不错的选择
以下是一个示例。我们定义了抽奖、活动准入、风险掌握等多个领域做事。在本系统中,我们须要集成多个领域做事,为客户端供应一套功能完备的抽奖运用做事。这个运用做事的组织如下:
代码演示9 LotteryApplicationService
结语在本文中,我们采取了分治的思想,从抽象到详细阐述了DDD在互联网真实业务系统中的实践。通过领域驱动设计这个强大的武器,我们将系统解构的更加合理。
但值得把稳的是,如果你面临的系统很大略或者做一些SmartUI之类,那么你不一定须要DDD。只管本文对血虚模型、演进式设计提出了些许意见,但它们在特定例模和详细场景下会更高效。读者须要针对自己的实际情形,做一定取舍,适宜自己的才是最好的。
本篇通过DDD来讲述软件设计的术与器,实质是为了高内聚低耦合,紧靠实质,按自己的理解和团队情形来实践DDD即可。
其余,关于DDD在迭代过程中模型腐蚀的干系问题,本文中没有提及,将在后续的文章中论述,敬请期待。
鉴于作者履历有限,我们对领域驱动的理解难免会有不敷之处,欢迎大家共同磋商,共同提高。
参考书本Eric Evans 《领域驱动设计》赵俐 盛海艳 刘霞等译. 公民邮电出版社,2016.
Vaughn Vernon《实现领域驱动设计》滕云译. 电子工业出版社,2014.
原文链接:https://kb.cnblogs.com/page/586236/