文档章节

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

猪刚烈
 猪刚烈
发布于 2014/10/12 11:47
字数 2672
阅读 28
收藏 1
点赞 0
评论 0

绪论:

三点:软件开发的方法论,讨论系统分层的必要性,提出构建领域模型的重要性;讨论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

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

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

Bernd Rücker ⋅ 01/03 ⋅ 2

市场是衡量一切的标准

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

边缘行者 ⋅ 2015/11/30 ⋅ 0

DDD领域驱动设计(Domain Driven Design)(转)

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

mcy247 ⋅ 2017/12/04 ⋅ 0

蚂蚁金服副总裁刘伟光:未来数字银行建设思路

本文作者: 刘伟光,蚂蚁金服副总裁,目前致力于蚂蚁金服技术的商业推广和生态建设。在加入蚂蚁金服前,他在企业软件市场深耕多年,创建Pivotal软件大中华区分公司,开创了企业级大数据以及企...

兔子酱 ⋅ 05/16 ⋅ 0

ReactOS 0.4.6 发布,兼容 XP 程序和驱动的开源操作系统

ReactOS 0.4.6 已发布,0.4.6 是实现对硬件支持的一个重要版本。该版本已经修复了几个双引导问题,现在以更安全的方式管理分区,以避免损坏分区列表结构。 ReactOS Loader 现在可以加载自定义...

局长 ⋅ 2017/09/03 ⋅ 71

案例推荐《中汇技术:打造银行间市场本外币交易背后的共享服务平台》

随着银行间市场新业务的开展,为了快速响应业务需求,更好的服务行业机构和会员单位,中汇系统逐步升级至分布式、服务化、高可用的技术架构。 中汇公司自主设计规划的企业架构资产库,包含丰...

飞天战略营 ⋅ 04/04 ⋅ 0

小议软件架构设计要点

如何更好地进行软件架构设计,这是软件工程领域中一个永恒的重点话题。过去几十年来,国际软件工程界在软件架构设计方面已经获得了长足发展,大量图书、文章和文献记载了这方面的成熟经验与成...

彭苏云 ⋅ 2014/10/16 ⋅ 0

领域驱动设计和开发实战-住房贷款处理系统

本文先阐述领域驱动设计的基本概念,然后以住房贷款系统的需求为引线,一步一步实战讲解如何进行领域驱动设计的开发,文章来源与网上,先贴出与大家一起分享。 李锡远 2010-8-20 背景 领域驱...

tavenli ⋅ 2010/08/20 ⋅ 0

从时间旅行的乌托邦,看状态管理的设计误区

Redux 的状态管理理念非常优雅,随之附带的时间旅行调试支持也非常酷炫。但这个特性是否是传说中的银弹,又会给使用者带来什么额外的负担呢?让我们重新思考一下吧。 什么是时间旅行? 在 20...

doodlewind ⋅ 2017/12/18 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 18分钟前 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部