`
wenrunchang123
  • 浏览: 249648 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

领域模型中的逻辑划分

 
阅读更多

最近在学习领域模型,一直纠结在领域层跟数据库层的划分,网上也查了不少资料,趁这段时间有空,好好总结下!

 

如何进行逻辑划分:

       在软件架构中,最常见的一种架构模式就是层式架构模式,即把一个系统按逻辑上的功能拆分成多个层,层与层之间保持单向依赖关系,每层只依赖于其直接下层,以保证每层的良好封装性和独立性。而层式架构模式最常用的就是:展示层-服务层-数据访问层,应用领域驱动设计(充血模型),服务层还应被进一步拆分为:应用服务层和领域层。

 

      综上所述,每个模块(子系统)又可以拆分成:展示层-应用服务层-领域层-数据访问层四个逻辑层。

 

      重要原则:每层只依赖于其直接下层,层与层之间不能形成循环依赖关系。

 

问题所在:

      领域层跟数据库层关系非常密切,所以我们放在一齐进行论述。两者的关系是:数据访问层依赖于领域层。

 

       先来看看领域层,领域层包含了该模块的领域对象和这些领域对象对应的仓库接口(Repository——对应J2EE设计模式的DAO,为了让设计和开发人员在进行建模的阶段尽量脱离具体技术去进行建模,我们建议使用Repository的模型术语取代DAO这个技术化的出于设计模式的术语),注意,这里包含的是仓库的“接口”,而非实现。对于这样的划分,一直存在着争议,最大的争议点在于:领域层的职责是负责领域业务逻辑处理和封装,不应该把数据访问的相关职责也纳入领域层。下面我们对这种设计进行分析和论述,并提供案例作为理据去论证这种设计的原因。

 

      在现实世界中,完成一个业务,并不需要有所谓“持久化”的操作,但这种模型一旦反映到软件中,“持久化”就变成了必不可少的步骤,我们从两个方面去进行分析:

 

    从领域层本身来看,由于领域对象本身包含了绝大部分的业务逻辑,在一些复杂的业务逻辑中,我们有时候出于性能等因素的考虑,是需要在领域对象被加载到内存后,在其业务逻辑中还需要通过额外的查询去查找完成某个业务所需的数据,而这些数据通常并不是领域对象自身的数据,而可能是从属这个领域对象的其他领域对象的数据,下面举一个例子来说明:

 

 

      上图是案例系统的出版物管理模块的其中一个主要的领域对象:Pulication——刊物,我们看到,Publication有两个从属的领域对象:PriceItem(历史价格明细)和IssueSchedule(历史出版发行计划),PriceItem保存的是对应Publication在不同时间段的不同销售区域的指定币种的销售价格,IssueSchedule保存的是对于Publication在不同时间段的出版发行计划。现在假设有一个订单业务,需要在某个时间段订阅某Publication,那么,为了计算订单的金额,则必须通过该Publication获取两个关键数据:该Publication在指定区域的指定币种的当前销售价格,以及该Publication在这段时间的发行期数。而这两个数据,均来源于Publication本身,也就意味着,Publication领域对象具有两个职责:获取当前区域指定币种销售价格——getCurrentPriceForCurrency和统计指定时间段的出版期数——countIssues,我们有两种方案去实现这个两个方法:

 

      一、通过ORM工具(Hibernate)对Publication的两个聚合对象集合PriceItem、IssueSchedule进行延迟加载设置,当调用该方法时,就可以不显式的调用Repository,而由ORM自动实现所有从属对象的加载。

 

      二、在两个方法的方法体内,显式的调用Repository接口提供的专有查询方法来获取相应数据,该专有查询方法并不把所有从属对象全部加载到内存,而是通过具体的持久化实现的查询语言(SQL、HQL、XQuery等),把符合条件的数据查询出来,而且,该专有查询方法并不带有任何与具体持久化实现耦合的信息,它只提供抽象,具体实现由数据访问层的领域对象仓库实现类提供。

 

      我们来对比一下两者,前者有两个明显的缺陷:1)从方法的职责上来说,方法只返回符合条件的结果,而这种实现会把所有从属数据(并且包括所有字段)都加载到内存,然后进行筛选,这种做法对内存的损耗是可以非常可观的(试想如果历史数据已经积累了很多年,数据量很大的情况)。2)这种设计(实现)方法是依赖于具体技术的,这就意味着,如果具体技术发生改变,会直接影响到Publication的模型,甚至产生更大的连锁效应。而第二种实现方案恰恰弥补了上述两种严重的缺陷。有人可能会认为,第二种方案的最大缺点是让领域对象与Repository形成了一种双向依赖关系而导致两者无法分开,但我们从本质上分析,第一种方案中,其实领域对象Publication依然无法逃脱其业务逻辑需要查询其从属领域对象这个潜在要求,只不过,第一种方案利用了ORM工具的技术手段,让代码中不需要建立这种显式的依赖而已。所以,从功能上来讲,无论何种实现方案,只要业务上有这样的要求(如上例),领域对象是无法与Repository完全脱离关系的。

 

      综上所述,我们从领域层本身出发,得出的结论是:领域对象与领域对象仓库之间存在着天生的互相依赖关系,这种关系在业务简单的时候可能体现不出来,但随着业务的进展,这种潜在的依赖关系很大机会会出现。因此,无论开始的时候业务是否足够简单,以至于领域对象的业务逻辑并不需要有额外的查询,出于对模型的统一的考虑,还是应该在开始设计的时候,把领域对象仓库接口划入领域层(即使它从职责划分原则上来看并不完全合理,但这世界上通常没有完美的解决方案,只有最适合的解决方案)。

 

      从应用服务层的角度看,对于领域层,应用服务层是其客户程序,因为应用服务层依赖于领域层提供领域对象完成相应服务。正如前面所述,在软件世界中,要完成一个业务,“持久化”几乎必不可少,那么,对于应用服务层来说,单独的使用领域对象或领域对象仓库并没有任何的意义,因为应用服务层如果要使用领域对象,则必须通过领域对象仓库对其进行加载,如果是创建新的领域对象,也必须(绝大部分情况)通过领域对象仓库实现领域对象的持久化。同时,应用服务层使用领域对象仓库的唯一目的就是实现对领域对象的增删改查操作。

      综上所述,我们从应用服务层的角度看,对于应用服务层来说,领域对象和领域对象仓库本身就是一体化的东西,无法割裂。

     经过上述的详细分析,我们已经有充足的理据支持领域对象与领域对象仓库被统一划入领域层的设计。

 

      我们再来分析数据访问层,前面已经说过,数据访问层是依赖于领域层的,它实际上是为应用服务层提供领域层领域对象仓库的具体实现,通过这样的设计,领域层虽然把数据访问的抽象纳入到其职责范围之内,但依然与具体的数据访问实现细节解藕,只要数据访问的抽象不发生变化,持久化实现发生变化只会影响数据访问层,对其他层是完全透明的。

 

  • 大小: 38.6 KB
分享到:
评论

相关推荐

    基于DDD的微服务设计和开发实战.pdf

    本文采用 DDD(领域驱动设计)作为微服务设计指导思想,通过事件风暴建立领域模型,合理划分领域逻辑和物理边界,建立领域对象及服务矩阵和服务架构图,定义符合 DDD 分层架构思想的代码结构模型,保证业务模型与...

    项目架构之传统三层架构和领域模型三层架构

    本文将对传统三层架构和对应的领域模型架构、以及每个模块的职责进行简单的说明。下图即示范项目的模块结构:传统三层架构是一种软件架构,是一种典型的、基于贫血模型的、面向过程的JavaWeb分层方式。该架构分为...

    领域驱动模型&CQRS学习

    领域模型通过聚合(Aggregate)组织在一起,聚合间有明显的业务边界,这些边界将领域划分为一个个限界上下文(BoundedContext)。采用DDD的设计思想,业务逻辑不再集中在几个大型的类上,而是由大量相对小的领域对象...

    领域驱动设计第二分卷

    第ⅰ部分 让领域模型发挥作用. 第1章 消化知识 5 1.1 有效建模的因素 9 1.2 知识消化 10 1.3 持续学习 11 1.4 知识丰富的设计 12 1.5 深层模型 15 第2章 交流及语言的使用 17 2.1 通用语言 17 2.2 利用对话...

    领域驱动设计第一分卷

    第ⅰ部分 让领域模型发挥作用. 第1章 消化知识 5 1.1 有效建模的因素 9 1.2 知识消化 10 1.3 持续学习 11 1.4 知识丰富的设计 12 1.5 深层模型 15 第2章 交流及语言的使用 17 2.1 通用语言 17 2.2 利用对话...

    2021年广东工业大学软件工程考试重点

    软件工程是计算机科学和信息技术领域的重要组成部分,本文将总结2021年广东工业大学软件工程考试的重点内容,涵盖数据流图、实体联系图、ER 图、数据字典、对象模型、类图、功能模型、用例图、设计工具、盒图、判定...

    机器学习算法在糖尿病预测中的应用 (1).pdf

    机器学习算法在糖尿病预测中的应用是机器学习技术在医学领域的重要应用之一。糖尿病是多发病和严重的慢性病,患病率呈现逐步上升的趋势。机器学习算法可以对糖尿病进行预测,从而帮助医生更好地诊断和治疗糖尿病。 ...

    分布式系统领域教程pdf

    1.4 我们的模型 1.5 互连网络 1.6 应用与标准 1.7 范围 1.8 参考资料来源 参考文献 习题 第2章 分布式程序设计语言 2.1 分布式程序设计支持的需求 2.2 并行/分布式程序设计语言概述 2.3 并行性的表示 2.4...

    快速数据挖掘数据分析实战RapidMiner工具应用第10章 线性回归与逻辑回归V1.1.pdf

    回归分析是通过建立模型来研究变量之间相互关系的密切程度、结构状态及进行模型预测的一种有效工具,在工商管理、经济、社会、医学和生物学等领域应用十分广泛。从19世纪初高斯提出最小二乘估计算起,回归分析的历史...

    机器学习及神经网络资料摘录

    在神经网络中,每个处理单元事实上就是一个逻辑回归模型,逻辑回归模型接收上层的输入,把模型的预测结果作为输出传输到下一个层次。通过这样的过程,神经网络可以完成非常复杂的非线性分类。 (3)SVM(支持向量机...

    紧跟科技前沿 提升应急效能——谈“机器学习”在应急领域的应用.pdf

    无监督的机器学习是根据特征将所有的任务划分到拥有相同特征的簇团。有监督的机器学习就是输入实例,训练程序学习得到规则。行评估,从而进一步优化模型。 二、机器学习在应急管理领域的应用 机器学习应用场景分析...

    数据库分库分表(sharding)系列

    一个好的建议是绘制一张数据库ER图或领域模型图,以这类图为基础划分shard,直观易行,可以确保开发人员始终保持清醒思路。对于是选择数据库ER图还是领域模型图要根据项目自身情况进行选择。如果项目使用数据驱动的...

    基于时空单词的两人交互行为识别方法

    采用条件随机场模型建模单人原子行为,在两人交互行为的语义建模过程中,人工建立表示领域知识(domain knowledge)的一阶逻辑知识库,并训练马尔可夫逻辑网用以两人交互行为的推理。两人交互行为库上的实验结果证明...

    OSS.Core:.net core下的领域开源电商网站,类库使用的标准库项目,集成微信和支付宝。 暂时还在开发阶段

    水平业务方向:以领域模型为基础,做水平层面的切割,单体解决方案下通过文件夹的形式,划分各服务领域模块,主要是两层文件结构:一. 首层结构根据业务关系划分:1. Basic 基础服务业务模块,也是全局业务模块,如...

    基于模拟退火的DPR系统划分-调度联合优化算法

    DPR系统中的重构区域划分和任务调度决定了整个系统的性能,因此如何对DPR系统的逻辑资源划分和调度问题进行建模,并设计高效的求解算法是保证系统性能的关键。在建立划分和调度模型的基础上,设计了基于模拟退火( ...

    软件工程-理论与实践(许家珆)习题答案

    瀑布模型的最大优点是将软件开发的各个阶段划分得十分清晰。(×) 3. 结构化方法的工作模型是使用螺旋模型进行开发。(×) 4. 结构化方法和JSP方法都不适合于大型软件的开发。(√) 5. 原型化开发方法包括生成原型...

    机器学习技术发展的综述与展望.pdf

    R.S.Michalski等人和E.A.Feigenbaum等人在著名的《人工智能手册》中把机器学习划分为从样例中学习、归纳学习、机械学习、类比学习、示教学习等。 机器学习技术的应用十分广泛,包括信息技术、计算机工程、机器学习...

    数据库系统概论试题及答案.doc

    10. 将数据库的结构划分成多个层次,是为了提高数据库的逻辑独立性和物理独立性。 知识点:数据库结构;逻辑独立性;物理独立性 11. 数据库(DB)、数据库系统(DBS)和数据库管理系统(DBMS)三者之间的关系是DBS 包括 ...

Global site tag (gtag.js) - Google Analytics