文档章节

领域驱动设计:理念,架构和若干重要细节(draft)

猪刚烈
 猪刚烈
发布于 2014/10/12 11:47
字数 2672
阅读 30
收藏 1

绪论:

三点:软件开发的方法论,讨论系统分层的必要性,提出构建领域模型的重要性;讨论OO技术是构建领域模型的主角;

争论:面向对象还是面向数据?一个

企业级应用的系统架构是应该面向对象还是面向数据的争论由来已久,并且从未停止过.这是一个非常尖锐且很难抉择的问题.产生这一问题的根源就在于当前企业级应用所依赖的数据库几乎无一例外的都是关系型数据库,关系型数据已经盛行了很多年,它也确实....但是后来随着面向对象技术的兴起,人们意识到面向对象技术在解决复杂业务问题上有着无可比拟的优势.这又驱使人们试图通过oo技术构建一个领域模型来处理业务逻辑.然后面向对象的领域模型和面向关系的数据模型天生存在着巨大的差异,这种差异使得企业级应用中构建领域模型变得

  在基于企业级应用必须依赖于关系数据库的前提下,人们并没有放弃通过OO技术构建领域模型的尝试,随着这方面的理论不断地成熟,具有实际可操作性的设计模式被总结并加以应用,人们逐渐地总结出了一整套将对象模型映射成关系模型的理论和方法,并产生了很多优秀的ORM框架,从而在关系模型和领域模型之间构建起一座桥梁,让开发人员得以通过OO技术来解决复杂的领域问题.

 

  客观地讲,当今的企业级应用的主流依然是以面向数据为主.

  我们无意要在这里比较孰优孰略,但是一般而言,对于那些数据量巨大,性能要求较高的系统,面向数据的架构要更好一些,而对于业务逻辑复杂,需求变动频繁的系统,面向领域的架构会更加适合.当然,正所谓技高人胆大,想要做到鱼和熊掌兼得,也不是不可能的.如何权衡整体的得失做出全局性的决策,让系统的综合性能达到最高,是一名架构师安身立命的核心技能之一.

1.领域模型:重中之重

从mvc谈起,涉及CC中关于软件复杂度管理的论述.

若干处来,MVC之所以成为一种广泛应的经久不衰的架构模式,根本原因在于它对一个软件系统做了合理的划分

自...以来,人类之所以能够完成各种宏大的工程,无不在应用这样一条放之四海而皆准的原则:将复杂任务分解为多个简单的子任务!也就是"关住点分离".MVC便是这一恩想下的典型架构

2.领域模型中的重要元素:

Entities

Value Objects

Aggregates

Domain Events

2.ORM不能回避的现实问题

在构建领域模型时,ORM确实是非常非常重要的一环.而且这一环也非常复杂,包括类继承体系与数据库的映射,抓取策略和缓存管理在内的一系列问题都是非常棘手的.即使我们现在已经有了像Hibernate这样优秀成熟的ORM框架,开发人员依然必须对ORM的原理和内部机制有深入地了解才能完成这一工作.否则领域模型很可能会受到数据库关系模型的"污染"进而被"同化",或者更常见的情况是因为糟糕的映射导致系统性能严重下降.讲到这里想说句题外话.笔者认识很多从事企业级应用开发的朋友,他们中有很多学习和使用Hibernate已经有三四年了,但是自觉依然不得要领,他们在项目中总是固定使用Hibernate中的"一小部分"功能,对一些所谓的"高级"机制从为涉及过,而且也找不适用的场合.这说明他们过去参与过的项目并没有构建过直正的领域模型.如果我们从领域模型的角度出发去思考对象应该如何从数据库中重建出来,我们就会发现我们会面临很多"必须"面对的问题,当你带着这些问题去学习一个ORM框架时,你会惊奇地发现,你所想到过的这些问题框架都给出了解决方案.学习ORM框架,必须要有面向对象方面的设计思想作为背景,总是从领域模型出发思考如何映射到数据库,如何从数据库中加载出对象才能领悟ORM框架的真实用意.

 

阻抗失配

关于性能的考量;可选方案.

3.IOC&AOP:重要的补充

虽然人们将IOC视为一种设计模式,但由于IOC所解决的问题几乎是所有OO系统都会遇到的,也可以说是OO技术本身在对象创建方面的缺失或者说是天生不足,这才导致IOC变得如此必须.,显然,IOC有着超越一般设计模式的重要地位,

如同rod jonason所赞叹:"再怎么赞扬IOC的好处都不为过!",IOC对于OO来说,就如同

4.团队管理和工作流程

5.应用领域驱动设计的面临的巨大挑战

面向数据还是面向领域?这是个问题!

 

为什么有如此之多的系统是面向数据而不是面向领域的?

 

 

 DDD一书中引入的独创性概念中,Aggregation是非常重要的一个.这个概念在此之前从末被提出过,它对进一步合理细分领域模型提供了非常好的理论依据.划分Aggregation是对领域模型的进一步深化,Aggregation能阐释领域模型内部对象之间的深层关联.对Aggregation的划分会直接映射到程序结构上.比如:DDD推荐按Aggregation设计model的子包.每个Aggregation配备一个Repository.Aggregation内部的非root对象是通过导航获得的.等等.

 

若干重要细节:

1.如何建立完整,自封闭的领域模型。举例:user.subscribe()和user.post(Message reply)

所有的外部请求到达应用层后,应用层知道如何把外部请求转换成驱动模型运转的指令,模型根据指令运转到达结果状态,外部视图选取模型中用户关心的部分呈现出来。

2.如何建模领域服务。

3.关于领域对象的依赖注入

参考:AspectJ in Action

http://www.infoq.com/news/2008/02/ddd-di-aop

Spring参考文档:6.8.1. Using AspectJ to dependency inject domain objects with Spring

 

4.Repository VS. DAO

Repository:位于领域层,面向Aggregation Root。

DAO:是面向数据访问的,不再需要。在领域领域驱动的项目中,去除DAO,淡化数据访问的概念,使用更加OO的Repository来替代。

5.关于领域对象和领域服务以及Repository之间的互相依赖问题。

当领域对象所需要的数据需要通过查询得到时应该怎么办?

1.通过为领域对象注入Repository来实现。

2.通过异步消息机制+Domain Event的形式来实现

考虑核心问题:领域对象可不可以依赖Repository?

 

一种声音:有个感觉是无论是DAO或者是Resposity,都是domain logic里的噪声。如果Domain logic也能透明的调用DAO或Respoisty,这样的domain模型会更完美,而且更关注业务。

 

这么说来repository只用来取root?从概念上讲不错,可是要知道往往一个root下面会有成百上千个node,这么巨大的一坨关系树我们用repository取出来然后在“关系之间游走”...是否有点滑稽?呃...或许我们能想到引入延迟加载,取出来的root下的二级node都用stub来占位;不过这又为污染我们纯洁的领域模型创造了良机...

 

我们常说的“领域模型”是一个分析模型,是对领域问题的整体表述,决不是编程的实现模型,一个领域概念不一定会隐射成一个类,有可能要映射很多的类。同样,我们的实现模型也有很多领域模型不设计或不关心的东西,像领域对象的crud,等。这对我们是一个启示,在从领域模型到实现模型的隐射过程中,我们要明白它们各自的本质。这对实现模型的组织结构也有一定的借鉴意义。

“领域模型”是一个针对业务逻辑抽象的模型,是一组概念的集合,和软件编程并无关系。

Repository的角色和Factory有些类似,它是一种编程层面上的Artifact,并无业务意义。对于它在架构中的位置,可能放在Model里会好些。就像是Factory总是伴随它的产品在一起一样。

 

架构:

1.包结构:

领域层应该按业务逻辑相关性(即aggregation)来组织。

应用层面向外部应用,不应该使用领域层的分割模式。展现层同样如此。

关于领域层的各对象:

领域对象和领域服务是领域模型的主体,地位相当,应等同对待。

Repository和Factory一样,属于设计和实现层面的衍生产物,在领域模型中没无对应概念,但是确实应该置于领域层!

 

DDDSample中把一些依赖具体框架的实现类划分到infrastructure包的做法,并不是一个好的做法。这分法试图突出领域层的“纯粹性”,但是,我们要明确,领域模型并不是领域层,领域层是领域模型的编程实现,既然是“实现”,那些具体类是不可避免的。它们是“实现模型”的重要组成部分!如果隔离到nfrastructure包,反而在包结构上让它与它们的实现类产生较大的距离,这种包结构好不到哪里去。

 

本文转载自:http://blog.csdn.net/bluishglc/article/details/4684029

共有 人打赏支持
猪刚烈
粉丝 22
博文 708
码字总数 110
作品 1
海淀
程序员
领域驱动设计与设计模式

作为程序员,你最喜欢在怎样的代码环境中编码?我们大部分时间是在维护代码或者在已有代码中添加需求,你是否吐槽过别人的代码有毒?我们希望别人的代码可读性好,易维护,添加新功能时,它有...

Jun_Wong
2017/12/23
0
0
事件、流程和长期运行的服务:工作流自动化的现代解决方案

本文要点 最近围绕微服务架构模式的讨论指出,事件驱动架构可以有效地解耦服务。 领域事件非常适合分散的数据管理、生成可读模型或者解决切面问题。然而,你最好不要实现复杂的点到点的事件链...

Bernd Rücker
01/03
0
2
市场是衡量一切的标准

“少年不知愁滋味,为赋新词强说愁,而今识愁滋味,却道天凉好个秋!”,这就是我对这些年我职业发展的比较贴近的比喻。 遥想当年,年少轻狂的我,凭借自己学习来的一些技术皮毛,一直标榜是...

边缘行者
2015/11/30
55
0
DDD领域驱动设计(Domain Driven Design)(转)

摘要 本文将介绍领域驱动设计(Domain Driven Design)的官方参考架构,该架构分成了Interfaces、Applications和Domain三层以及包含各类基础设施的 Infrastructure。本文会对架构中一些重要组件...

mcy247
2017/12/04
0
0
年薪百万的大数据开发工程师的入门书单(收藏)

前言 你们是不是都听过一句话:谷歌比你自己更了解你 事实上,这句话并不是毫无根据,我们周边的一切无不体现数据的重要性,你想想,我们对自己的看法会受到多种主观和客观的因素影响,但谷歌...

风火大数据
07/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

深入解析MySQL视图VIEW

Q:什么是视图?视图是干什么用的? A:视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。   通过视图,可以展现基表的部分数据;...

IT--小哥
34分钟前
1
0
虚拟机学习之二:垃圾收集器和内存分配策略

1.对象是否可回收 1.1引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时候计数器值为0的对象就是不可能...

贾峰uk
43分钟前
1
0
smart-doc功能使用介绍

smart-doc从8月份底开始开源发布到目前为止已经迭代了几个版本。在这里非常感谢那些敢于用smart-doc去做尝试并积极提出建议的社区用户。因此决定在本博客中重要说明下smart-doc的功能,包括使...

上官胡闹
昨天
7
0
JavaEE——Junit

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。 Junit Junit又名单元测试,Junit是用来测试Jav...

凯哥学堂
昨天
5
0
读《美丽新世界》

一、背景 十一国庆节从重庆回深圳的时候,做得绿皮车,路上看了两本书:李笑来的《韭菜的自我修养》和禁书《美丽新世界》。 上篇文章已经分享了 读《韭菜的自我修养》,这篇文章来记录一下《...

tiankonguse
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部