[转] .NET领域驱动设计—初尝(原则、工具、过程、框架)
阅读目录:
- 1.原则
- 1.1.精简聚合
- 1.2.分离用例与接口功能(设计模式的用武之地)
- 2.工具、框架、组件
- 3.过程
1】原则
原则对于任何一项技术实现来说都是至关重要的,在设计某一个系统功能的时候我们讲究的是设计原则:
【单一职责原则Single Responsibility Principle、里氏替换原则Liskov Substitution Principle、依赖倒置原则Dependence Inversion Principle、接口隔离原则Interface Segregation Principle、迪米特法则Law Of Demeter、开闭原则Open Close Principle】。
在架构设计的时候我们也讲究架构原则:
【分层原则、避免循环依赖】。
不仅仅在技术领域在做人做事都要讲究原则,违背原则那么等待你的将是无情的惩罚。
对于DDD的设计我们也有相应的原则需要遵守,当然如果不遵守在前期看不出什么区别,但是到开发阶段问题就会暴露出来。
我们来看两个基本的设计原则问题。
【精简聚合】
精简聚合的设计原则无疑是最重要的。一些软件工程方法论书籍经常指导我们进行UML业务建模,"在这个阶段不需要考虑任何技术实现问题”,我按照这样的指导原则进行了UML的设计然后顺利的创建出ER关系图,结果发现那样的数据库结构根本不能作为最终的项目开发数据库。哪里出问题了?我反复查询指导书籍后来在专业的DDD书籍上看到了一句大概这样的话:
【“不以技术实现为前提的设计都是纸上谈兵”】。
我想这句话很真实的描述了方法论与企业应用之间的鸿沟,很多技术思想或者理论确实很好,但是要想用起来需要解决很多问题。DDD也避免不了这个问题,怎么避免在设计UML模型的时候不会导致设计过度的问题,这里我们只需要遵守【精简聚合】原则就不会导致设计过度问题。
在前面的例子当中我们设计一个完整的UML领域模型,但是我们并没有对它进行【精简聚合】重构,所以它存在的问题就是无法进行项目开发。
1.1图
我们构建出来的领域模型初步版本应该是上图这样的,实体与实体之间是有强联系的,聚合之间的关联太大,导致牵一发而动全身。如果按照这种关系创建数据库那么数据库之间的主\外键肯定很多,对数据库的设计造成了影响。这样的关系如果在程序中使用也会存在很多问题,我们无法进行少数聚合的使用,当我们使用某一个聚合的时候它会接二连三的把相关联的聚合都给拖出来,不仅在查询的时候妨碍而且在Factory创建聚合的时候也会存在无法构造的问题,不管在对聚合Repository进行任何操作的时候都会影响程序逻辑,所以我们需要对一个复杂的庞大的关系进行拆分。
将红线的部分全部断开,聚合之间通过Id进行关联,这样就会变的很清晰。因为很少程序中会在某一个业务逻辑点上需要所有的业务模型参与,这样既方便了程序的开发也方便了数据库的设计,更方便了ORM的使用。ORM的延迟加载其实就是为了聚合之间的依赖,可以在需要的时候在去查询需要的模型。但是这样虽然程序可以说的过去,那么数据库的设计就说不过去了。对于不同的ORM框架的映射原理不同,在构造模型的时候是需要稍微的调整的,比如在EntityFramework中,它能支持的映射方案你保证你的模型能顺利的映射过去,这里就不扯了后面有一个详细的项目做全面实践,到时候在具体问题具体分析。
最后我们看一下分解后的类图:
1.2图
这样一来一块一块很清晰,都能直接使用相关的核心领域模型,也不需要担心ORM框架的延迟加载的问题。
【分离用例与功能接口(设计模式的使用之地)】
分离用例与功能接口其实也是初次接触DDD的朋友都会犯的职业病,因为我们都熟悉面向对象设计。在进行UML建模的时候我们都非常喜欢抽象,会很清楚的把具有泛化关系的用继承来表示,比如【用户类型】,不同的用户具有不同的行为权限,在初步设计的时候我们一般都会建立关于用户的一个继承关系来表达泛化的业务模型。但是在编码阶段会发现很明显的问题就是我们把关于Repository的行为包含到了发起用例的用户聚合当中去了,这样说可能有点抽象。我们还是用例子来分析;
1.3图
上图中我将【Admin】和【配送】用例分开了,想表达是不能将关于配送的行为放在【Admin】中。在我们对有关权限进行建模的时候经常会潜意识的将各自的行为放在了各自的角色当中,如果后期存在多角色共享行为的就将写在抽象的类中使用虚方法向下传递。问题就出在关于角色行为里,我们知道如果有行为那么就有可能在该行为里面执行有关其他聚合的IRepository操作,这样一来将会把领域模型搞的很乱,无法垂直分析。
1.4图
DDD讲究领域驱动,在我们看来【Dispatching】、【CheckOrders】都是继承管理员角色,管理员属于后台管理人员,意味着企业的员工。对消费者来说他们就是管理人员。同样消费者也会存在相同的情况,消费者可能存在很多种类型,有VIP系列的(VIP1\VIP2\VIP3…),有钻石会员之类的。如果这样设计的话并不能说是错的,这也完全符合DDD的思想要求,但是实际情况下却是不理想的。
这里就用到了我们长期使用的设计模式了,我们可以通过设计模式中的很多中模式来将用户与行为分离开来,再将使用的规则条件抽象出来就完全独立了用户,用户在使用的时候不会存在直接的行为归属,但是事实上他们确实是有行为。
1.5图
用专业的DDD术语讲“规约模式”,将业务规则抽取出来对象化,甚至到最后都可以进行规则的配置化。最让我们兴奋的是,我们苦心学习的设计模式终于可以在系统设计中大面积的使用了,难道不是一件很惊喜的事情吗!
2】工具、框架、组件
任何一种架构都是需要框架、工具的支撑才能变的完美。
当我们在某种架构下进行开发的时候,我们必须需要很多工具、框架的支撑才能让开发工作变的很便捷,这也和【敏捷开发】的思想一样。在传统的三层架构下开发我们都需要 "对象映射"、"AOP\IOC” 等等类似的辅助框架,目的是为了架构前行的可能性。在DDD中我们也需要很多目前还没有出现的很多工具、框架,在.NET平台中目前来看只有EntityFramework框架算是为了DDD做了很多工作,如果我们的领域模型无法与数据库进行映射,那么领域模型开发所要付出的代价将是很大。
在设计阶段我们缺乏一个面向特定领域的建模工具,这种工具与UML不同,UML太技术化通用化。DDD中经常会提起【领域专家】一角,他是最具有权威性的领域领头人,我们所创建出来的UML他们未必能看得懂,通过技术人员技术化之后形成UML其实已经变味,【领域专家】是懂非懂的无法做到肯定的保证。如果能把领域模型语言化,那么这个将是一大成就。【领域专家】对领域中的任何事物、人物、环节都很熟悉,但是他无法表达清楚自己的想法,如果能有一个工具辅助他的设计,该工具能将设计后的模型进行平滑等价的技术化变成代码模型或者数据库模型,这一条鸿沟如果能跨越那么对行业来说具有很大影响力。
1.8图
如果我们能等价的将上图中的真实模型进行技术化,那么真的每个人都会喜欢需求分析、分析设计。
既然是模型驱动设计,我们在给用户分析类似这样一套系统的时候,前提是我们已经对里面的所有细节进行了抽象封装,每一个过程都是可以拆分的,最后能合并在一起形成一个整体的业务模型。当然这里只是一种技术展望,也是我们奋斗和理想的目标。
推荐一本最新Martin Fowler的书:《领域特定语言》
3】过程
DDD不是一种纯技术实现,而是一整套开发思想,它贯穿软件开发的所有生命周期。从我们开发接触领域,对领域知识进行深入的消化,这些都是DDD所强调的。那么在我们日常开发过程中,我们该如何处理这些过程,需求不会再像以前那样是一份杂乱无章的草稿,而是一个内容丰富的领域模型草图。这样的要求对团队对部门甚至对公司来说都是一个提升,要想做到完全的DDD过程其实很难。
公司领导如何看待这样的开发方式,我们多数人都是在一些非专业研发类的公司工作,领导希望能尽早的看到东西,这很矛盾,需要好的东西但是不按照好的东西做法来做。如果有幸能有一个面向DDD、敏捷、XP的研发团队工作,那么可以视项目为一件终身的艺术品。
这两篇文章主要是一些本人对DDD的感悟,分享给大家。
后面一篇文章将会详细的使用一个DDD架构的小系统作为案例给大家分享,里面将包括从需求的分析建模、设计模式的使用、数据库映射、EntityFramework的使用等等,可以作为真实项目开发的依据。
转自:http://www.cnblogs.com/wangiqngpei557/
[转] .NET领域驱动设计—初尝(原则、工具、过程、框架)的更多相关文章
- .NET领域驱动设计—初尝(一:疑问、模式、原则、工具、过程、框架、实践)
.NET领域驱动设计—初尝(一:疑问.模式.原则.工具.过程.框架.实践) 2013-04-07 17:35:27 标签:.NET DDD 驱动设计 原创作品,允许转载,转载时请务必以超链接形式标明 ...
- .NET领域驱动设计—初尝(三:穿过迷雾走向光明)
开篇介绍 在开始这篇富有某种奇妙感觉的文章之旅时我们先短暂的讨论一下关于软件开发方法论的简要: 纵观软件开发方法论,从瀑布模型.螺旋模型.RUP(统一软件开发过程).XP(极限编程).Agile(敏捷 ...
- [转] .NET领域驱动设计—初尝(疑问、模式、原则、工具、过程、框架、实践)
阅读目录: 1.1.疑问 1.1.1.UML何用 1.1.2.领域建模 1.2.模式 1.3.原则 1.5.过程 1.6.框架 1.7.项目演示 最近在研究DDD颇有收获,所以整理出来跟大家分享,共同 ...
- .NET应用架构设计—面向查询的领域驱动设计实践(调整传统三层架构,外加维护型的业务开关)
阅读目录: 1.背景介绍 2.在业务层中加入核心领域模型(引入DomainModel,让逻辑.数据有家可归,变成一个完整的业务对象) 3.统一协调层Application Layer(加入协调层来转换 ...
- .NET领域驱动设计—实践(穿过迷雾走向光明)
阅读目录 开篇介绍 1.1示例介绍 (OnlineExamination在线考试系统介绍) 1.2分析.建模 (对真实业务进行分析.模型化) 1.2.1 用例分析 (提取系统的所有功能需求) 1.3系 ...
- [转] .NET领域驱动设计—实践(穿过迷雾走向光明)
阅读目录 开篇介绍 1.1示例介绍 (OnlineExamination在线考试系统介绍) 1.2分析.建模 (对真实业务进行分析.模型化) 1.2.1 用例分析 (提取系统的所有功能需求) 1.3系 ...
- 领域驱动设计学习之路—DDD的原则与实践
本文是我学习Scott Millett & Nick Tune编著的<领域驱动设计模式.原理与实践>一书的学习笔记,一共会分为4个部分如下,此文为第1部分: ① 领域驱动设计的原则 ...
- 基于ABP落地领域驱动设计-02.聚合和聚合根的最佳实践和原则
目录 前言 聚合 聚合和聚合根原则 包含业务原则 单个单元原则 事务边界原则 可序列化原则 聚合和聚合根最佳实践 只通过ID引用其他聚合 用于 EF Core 和 关系型数据库 保持聚合根足够小 聚合 ...
- 基于ABP落地领域驱动设计-03.仓储和规约最佳实践和原则
目录 系列文章 仓储 仓储的通用原则 仓储中不包含领域逻辑 规约 在实体中使用规约 在仓储中使用规约 组合规约 学习帮助 围绕DDD和ABP Framework两个核心技术,后面还会陆续发布核心构件实 ...
随机推荐
- 移动端H5开发 (滑动事件)
最近一直在做手机App H5的开发,在开发过程中,经常会遇到很多滑动事件,写个demo,分享自己的一些写法.(如写的不好,轻喷!) 直接贴代码 html css代码 <!DOCTYPE html ...
- 自定义list排序
使用扩展方法OrderBy,OrderByDescending,效果优良. 实现代码如下: private static void SortByExtensionMethod() { List< ...
- 《Thinking in Java》 And 《Effective Java》啃起来
前言 今天从京东入手了两本书,<Thinking in Java>(第四版) 和 <Effective Java>(第二版).都可以称得上是硬书,需要慢慢啃的,预定计划是在今年 ...
- 微信小程序框架
框架 小程序开发框架的目标是通过尽可能简单.高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务. 框架提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的 ...
- .net使用RabbitMQ
前面的两篇博文算是把RabbitMQ的基础了解了下,今天学习.Net 中RabbitMQ的使用.原本这篇博文是应该上周写的,可在自己使用的过程中出现了一个问题bug:就是在连接服务端时,一直报下面的错 ...
- [大数据]-Elasticsearch5.3.1+Kibana5.3.1从单机到分布式的安装与使用<1>
一.Elasticsearch,Kibana简介: Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎.无论在开源还是专有领域, Lucene可以被认为是迄今为止最先 ...
- js快速去除数组重复项
function unique1(arr) { var tmp = new Array(); tmp.push(arr[0]); for(var i=0;i<arr.length;i++) { ...
- 关于jQuery插件imgAreaSelect基础讲解
关于ImgAreaSelect, 是一jQuery插件,它支持用户通过鼠标拖曳选择图片的一部分,如图片拖曳.图片编辑等~~来具体看一下 1.先下载imgAreaSelect插件 下载地址: 英文:h ...
- JVM方法调用
当我们站在JVM实现的角度去看方法调用的时候,我们自然会想到一种分类: 1.编译代码的时候就知道是哪个方法,永远不会产生歧义,例如静态方法,private方法,构造方法,super方法. 2.运行时才 ...
- 在CentOS上使用Jexus托管运行 ZKEACMS
ZKEACMS Core 是基于 .net core 开发的,可以在 windows, linux, mac 上跨平台运行,接下来我们来看看如何在 CentOS 上使用Jexus托管运行 ZKEACM ...