Domain Driven Design GAP平台领域驱动设计

Domain Driven Design ——GAP平台领域驱动设计

演讲人:ITARI

日 期:2009-09-15

Book Store :GAP 的DDD 应用

GAP 平台的领域驱动设计

事务脚本和领域模型

领域驱动简介 A. 什么是DDD

B. DDD 的分层架构

C. DDD 的基本构成要素

大纲

?领域驱动设计

2004年著名建模专家Eric Evans发表了他最具影响力的著名书籍:《Domain-Driven Design –Tackling Complexity in the Heart of Software》(中文译名:领域驱动设计—软件核心复杂性应对之道),书中提出了“领域驱动设计(简称

DDD)”的概念。 

?领域驱动设计

领域驱动设计事实上针对是OOAD的一个扩展和延伸,DDD基于面向对象分析与设计技术,对技术框架进行了分层规划,同时对每个类进行了策略和类型的划分。 

领域模型是领域驱动的核心,采用DDD的设计思想,业务逻辑不再集中在几个大型的类上,而是由大量相对小的领域对象(类)组成,这些类具备自己的状态和行为,每个类是相对完整的独立体,并与现实领域的业务对象映射。领域模型就是由这样许多的细粒度的类组成。基于领域驱动的设计,保证了系统的可维护性、扩展性和敏捷性,在处理复杂业务逻辑方面有着先天的优势。 

??成熟、清晰的分层架构

??领域对象与现实世界的业务映射

??明确的职责划分

分层架构

??领域对象是核心

??领域对象复用:完整的业务对象描述

??设计复用:设计基于领域对象而非数据库复用

使用场景??具备复杂业务逻辑的软件开发??对设计和开发人员要求较高??不适用普通CRUD的业务??软件的维护性和扩展性良好

DDD的特性

不使用DDD会如何呢?

?Design without DDD:

不去建立和开发领域模型,会导致应用架构出现“胖服务

层”和“贫血的领域模型”,在这样的架构中,Service层开始积聚越来越多的业务逻辑,而领域对象则成为只有getter和setter方法的数据载体。这种做法还会导致领域特定业务逻辑和规则散布于多个的Service类中,有些情况下还会出现重复的逻辑 

在大多数情况下,贫血的领域模型没有成本效益;它们不会给公司带来超越其它公司的竞争优势,因为在这种架构里要实现业务需求变更,开发并部署到生产环境中去要花费太长的时间 

用户界面/展现层负责向用户展现信息以及解释用户命令。应用层 很薄的一层,用来协调应用的活动。它不

包含业务逻辑。它不保留业务对象的状态,

但它保有应用任务的进度状态。

领域层 本层包含关于领域的信息。这是业务软件

的核心所在。在这里保留业务对象的状态,

对业务对象和它们状态的持久化被委托给

了基础设施层。

基础设施层 本层作为其他层的支撑库存在。它提供了

层间的通信,实现对业务对象的持久化,

包含对用户界面层的支撑库等作用。

DDD的领域模型架构(Ref POJO in action)

◆?领域驱动设计对Object做了明确的职责和策略划分

◆?Entities:Objects with a distinct identity;实体类,具备唯一

ID,持久化,具备业务逻辑,对应现实世界业务

◆?Value objects:Objects with no distinct identity;内存中的对

象,传参,和实体类的比较方式不同

◆?Factories:Define methods for creating entities,工厂类,可

用来创建多个实体

◆?Repositories:Manage collections of entities and

encapsulate the persistence framework;持久化层,DAO

◆?Services:Implement responsibilities that can’t be assigned

to a single class and encapsulate the domain model;服务

层,为上层提供操作的接口,负责对领域对象进行调度和封

装,同时可以对外提供各种形式的服务

Book Store :GAP 的DDD 应用

GAP 平台的领域驱动设计

事务脚本和领域模型 领域驱动简介

大纲

A. 事务脚本

B. 领域模型

事务脚本模式(Transaction Script)

◆?使用过程来组织业务逻辑,每个过程处理来自表现层

的单个请求

◆?大部分业务应用都可以被看成一系列事务

◆?在某些情况下,业务处理会像直接处理数据库信息一样简单,

例如CRUD

◆?事务脚本将这些所有的业务逻辑组织成单个过程,在过程中

层处理

直接调用数据库,如有业务逻辑在Service

事务脚本模式(使用场景)

◆?事务脚本的特点:简单容易理解,面向过程设计

◆?对于少量逻辑的业务应用来说,事务脚本模式非常简单自然,

性能良好,容易理解

◆?代码生成器生成的程序基本都是事务脚本模式

◆?一个事务的处理不会影响其他事务

◆?缺点也很明显,对于复杂的业务逻辑处理力不从心,难以保

持良好的设计,事务之间的冗余代码不断增多,通过复制粘

贴方式进行复用,可维护性和扩展性变差

领域模型(Domain Model)

◆?面向对象设计

◆?领域模型具备自己的属性行为状态,并与现实世界的业务对

象相映射

◆?明确的职责划分,各个领域对象元素配合解决实际业务应用

和规则

◆?复用性,可维护性,扩展性

◆?设计模式的应用

◆?缺点:相对复杂,性能问题

领域模型(复杂应用)

Book Store :GAP 的DDD 应用

GAP 平台的领域驱动设计 事务脚本和领域模型

领域驱动简介

大纲

A. GAP 分层架构

B. GAP DDD 要素

C. 如何构建领域应用

◆?View:展示层,由于GAP平台主要面向B/S架构,展示层主要

由web资源文件组成,包括JSP,JS和大量的界面控件,采用了AJAX技术,负责向用户展现丰富的界面信息,并执行用户的命令

◆?Control:控制层,负责展示层请求的转发、调度和验证,同

时处理后台返回的异常信息,同时控制层可以通过Action做远程的请求

◆?Domain:领域层,是系统最为丰富的一层,主要负责处理整

个系统的业务逻辑。这一层主要包括业务服务和领域模型,同时负责系统的事务管理

◆?Persistence:持久化层,主要负责数据持久化,支持O/R

Mapping和JDBC,对数据源的访问提供多种访问方式。

系统的控制层、领域层和持久化层元素都有IOC容器统一管理,实现完全的接口分离和解耦。

面向对象设计之定义领域服务

面向对象设计之定义领域服务 若遵循基于面向对象设计范式的领域驱动设计,并用以应对纷繁复杂的业务逻辑,则强调领域模型的充血设计模型已成为社区不争事实。我将Eric提及的战术设计要素如EnTIty、Value Object、Domain Service、Aggregate、Repository与Factory视为设计模型。这其中,只有EnTIty、Value Object和Domain Service才能表达领域逻辑。 为避免贫血模型,在封装领域逻辑时,考虑设计要素的顺序为: Value Object -》EnTIty -》Domain Service 切记,我们必须将Domain Service作为承担业务逻辑的最后的救命稻草。之所以把Domain Service放在最后,是因为我太清楚领域服务的强大魔力了。开发人员总会有一种惰性,很多时候不愿意仔细思考所谓职责(封装领域逻辑的行为)的正确履行者,而领域服务恰恰是最便捷的选择。 就我个人的理解,只有满足如下三个特征的领域行为才应该放到领域服务中: 领域行为需要多个领域实体参与协作 领域行为与状态无关 领域行为需要与外部资源(尤其是DB)协作 假设某系统的合同管理功能允许客户输入自编码,该自编码需要遵循一定的编码格式。在创建新合同时,客户输入自编码,系统需要检测该自编码是否在已有合同中已经存在。针对该需求,可以提炼出两个领域行为: 验证输入的自编码是否符合业务规则 检查自编码是否重复 在寻找职责的履行者时,我们应首先遵循信息专家模式,即拥有信息的对象就是操作该信息的专家,因此可以提出一个问题:领域行为要操作的数据由谁拥有?针对第一个领域行为,就是要确认谁拥有自编码格式的验证规则?有两个候选: 拥有自编码信息的合同(Contract)对象

领域驱动设计(DDD)架构的实践

领域驱动设计(DDD)架构的实践

前言 至少30年以前,一些软件设计人员就已经意识到领域建模和设计的重要性,并形成一种思潮,Eric Evans将其定义为领域驱动设计(Domain-Driven Design,简称DDD)。在互联网开发“小步快跑,迭代试错”的大环境下,DDD似乎是一种比较“古老而缓慢”的思想。 然而,由于互联网公司也逐渐深入实体经济,业务日益复杂,我们在开发中也越来越多地遇到传统行业软件开发中所面临的问题。本文就先来讲一下这些问题,然后再尝试在实践中用DDD的思想来解决这些问题。 问题 过度耦合 业务初期,我们的功能大都非常简单,普通的CRUD就能满足,此时系统是清晰的。随着迭代的不断演化,业务逻辑变得越来越复杂,我们的系统也越来越冗杂。模块彼此关联,谁都很难说清模块的具体功能意图是啥。修改一个功能时,往往光回溯该功能需要的修改点就需要很长时间,更别提修改带来的不可预知的影响面。

下图是一个常见的系统耦合病例。 订单服务接口中提供了查询、创建订单相关的接口,也提供了订单评价、支付、保险的接口。同时我们的表也是一个订单大表,包含了非常多字段。在我们维护代码时,牵一发而动全身,很可能只是想改下评价相关的功能,却影响到了创单核心路径。虽然我们可以通过测试保证功能完备性,但当我们在订单领域有大量需求同时并行开发时,改动重叠、恶性循环、疲于奔命修改各种问题。 上述问题,归根到底在于系统架构不清晰,划分出来的模块内聚度低、高耦合。

有一种解决方案,按照演进式设计的理论,让系统的设计随着系统实现的增长而增长。我们不需要作提前设计,就让系统伴随业务成长而演进。这当然是可行的,敏捷实践中的重构、测试驱动设计及持续集成可以对付各种混乱问题。重构——保持行为不变的代码改善清除了不协调的局部设计,测试驱动设计确保对系统的更改不会导致系统丢失或破坏现有功能,持续集成则为团队提供了同一代码库。 在这三种实践中,重构是克服演进式设计中大杂烩问题的主力,通过在单独的类及方法级别上做一系列小步重构来完成。我们可以很容易重构出一个独立的类来放某些通用的逻辑,但是你会发现你很难给它一个业务上的含义,只能给予一个技术维度描绘的含义。这会带来什么问题呢?新同学并不总是知道对通用逻辑的改动或获取来自该类。显然,制定项目规范并不是好的idea。我们又闻到了代码即将腐败的味道。 事实上,你可能意识到问题之所在。在解决现实问题时,我们会将问题映射到脑海中的概念模型,在模型中解决问题,再将解决方案转换为实际的代码。上述问题在于我们解决了设计到代码之间的重构,但提炼出来的设计模型,并不具有实际的业务含义,这就导致在开发新需求时,其他同学并不能很自然地将业务问题映射到该设计模型。设计似乎变成了重构者的自娱自乐,代码继续腐败,重新重构……无休止的循环。 用DDD则可以很好地解决领域模型到设计模型的同步、演化,最后再将反映了领域的设计模型转为实际的代码。

[教程]-领域驱动设计(DDD)

本文内容提要: 1. 领域驱动设计之领域模型 2. 为什么建立一个领域模型是重要的 3. 领域通用语言(Ubiquitous Language) 4.将领域模型转换为代码实现的最佳实践 5. 领域建模时思考问题的角度 6.领域驱动设计的标准分层架构 7. 领域驱动设计过程中使用的模式 关联的设计 实体(Entity) 值对象(Value Object) 领域服务(Domain Service) 聚合及聚合根(Aggregate,Aggregate Root) 工厂(Factory) 仓储(Repository) 8. 设计领域模型的一般步骤 9. 领域驱动设计的其他一些主题 10. 一些相关的扩展阅读 领域驱动设计之领域模型 2004年Eric Evans发表Domain-Driven Design – Tackling Complexity in the Heart of Software (领域驱动设计),简称Evans DDD。领域驱动设计分为两个阶段: 1. 以一种领域专家、设计人员、开发人员都能理解的―通用语言‖作为相互交流的工具,在不断交流的过程中不断发现一些主要的领域概念,然后将这些概念设计成一个领域模型; 2. 由领域模型驱动软件设计,用代码来表现该领域模型。 由此可见,领域驱动设计的核心是建立领域模型。领域模型在软件架构中处于核心地位;软件开发过程中,必须以建立领域模型为中心。 为什么建立一个领域模型是重要的 领域驱动设计告诉我们,在通过软件实现一个业务系统时,建立一个领域模型是非常重要和必要的,因为领域模型具有以下特点: 1. 领域模型是对具有某个边界的领域的一个抽象,反映了领域内用户业务需求的本质;领域模型是有边界的,只反应了我们在领域内所关注的部分;

领域知识模型

领域知识模型——企业应用系统的智慧中枢 摘要:企业应用系统有海量的领域对象和丰富的领域知识,这些领域知识一般被作为领域对象的业务逻辑或规则定义。本文认为领域知识是领域模型的一个知识切面且自成体系,结合领域驱动设计[DDD]和面向方面编程[AOP]的方法,对领域知识进行建模和应用,让面向业务活动的领域应用对象只需关注业务过程的组织和管理,用AOP技术把领域知识应用到具体的业务处理策略中,使领域应用对象和领域知识对象有更好内聚性且更轻量,不仅可大幅提升它们的可管理性和复用性,而且对系统开发效率、动态业务建模和装配能力也大有益处。 关键词:领域知识、领域模型、领域驱动设计、企业应用架构、DDD、AOP 1.前言 领域模型[Domain Model]和领域驱动设计[Domain-Driven Design][1]是目前在应用软件行业非常热门和前沿的话题,普遍认为这是构建高质量复杂系统最有效的方法和技术。领域模型在业界比较认可的定义是:领域模型是领域内的概念或者现实世界中对象的可视化表示,又称为概念模型、领域对象模型、分析对象模型,它专注于分析领域问题本身,领域对象是与技术无关的纯业务对象。领域建模的核心理念是把业务对象的属性、规则和职能封装在领域对象中,而不是被分散在用户界面层、应用层和持久化层中。 领域建模一般情况下是从应用功能或用例[Use Case]入手,因此,领域模型中的领域对象也是直接与应用功能或用例相关的业务对象,而这些领域对象模型涉及的领域知识,一般都作为领域对象的逻辑或者规则而存在。知识是应用领域问题的本质,是特定领域中一系列业务对象共有的知识切面,这个知识切面自成体系,本文中把这个知识体系的模型称为领域知识模型,与具体应用功能或者活动相关的领域对象模型称为领域应用模型。为了便于理解这些概念,我用一个与企业管理无关的通俗的例子来说明知识模型和应用模型的关系,比如对我喜欢的台球运动进行游戏建模,美式九球模型或者英式斯诺克模型是具体的领域应用模型,球台、球、球杆、运动员等是应用领域模型的核心领域对象,但要做出好玩的仿真游戏,台球碰撞中的基本物理知识是不可或缺的,用牛顿理论作为领域知识模型就涉及到质量、速度、动量等概念和动量守恒及能量守恒模型。知识模型是高度抽象并且可独立存在的模型,也是可以在各种业务情景中复用的模型,就如前面提到的台球游戏用到的牛顿理论模型,同样可以应用到保龄球游戏以及任何一款涉及到碰撞的游戏场景。企业管理领域也同样存在大量的知识模型,本文笔者致力于把企业管理领域涉及的领域知识进行分离、建模和应用的可行性分析和实践,希望以此进一步提升大型复杂企业应用系统的质量、动态业务建模和装配能力及组件复用水平。 2.企业应用系统中的领域知识问题分析 企业应用系统已逐渐成为企业经营管理的一体化应用平台,面向业务流程的行业深度应用

DDD领域驱动设计基本理论知识总结

?领域驱动设计之领域模型 ?为什么建立一个领域模型是重要的 ?领域通用语言(UBIQUITOUS LANGUAGE) ?将领域模型转换为代码实现的最佳实践 ?领域建模时思考问题的角度 ?领域驱动设计的经典分层架构 ?用户界面/展现层 ?应用层 ?领域层 ?基础设施层 ?领域驱动设计过程中使用的模式 ?所有模式的总揽图 ?关联的设计 ?实体(Entity) ?值对象(Value Object) ?领域服务(Domain Service) ?应用层服务 ?领域层服务 ?基础层服务 ?聚合及聚合根(Aggregate,Aggregate Root) ?聚合有以下一些特点: ?如何识别聚合? ?如何识别聚合根? ?工厂(Factory) ?仓储(Repository) ?设计领域模型的一般步骤 ?在分层架构中其他层如何与领域层交互 ?对于会影响领域层中领域对象状态的应用层功能 ?关于Unit of Work(工作单元)的几种实现方法 ?对于不会影响领域层中领域对象状态的查询功能 ?为什么面向对象比面向过程更能适应业务变化 ?领域驱动设计的其他一些主题 ?一些相关的扩展阅读 ?CQRS架构 ?Event Sourcing(事件溯源) ?DCI架构 ?四色原型分析模式 ?时刻-时间段原型(Moment-Interval Archetype) ?参与方-地点-物品原型(Part-Place-Thing Archetype)?描述原型(Description Archetype) ?角色原型(Role Archetype) 领域驱动设计之领域模型

加一个导航,关于如何设计聚合的详细思考,见这篇文章。 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity in the Heart of Software (领域驱动设计),简称Evans DDD。领域驱动设计分为两个阶段: 以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然后将这些概念设计成一个领域模型; 由领域模型驱动软件设计,用代码来实现该领域模型; 由此可见,领域驱动设计的核心是建立正确的领域模型。 为什么建立一个领域模型是重要的 领域驱动设计告诉我们,在通过软件实现一个业务系统时,建立一个领域模型是非常重要和必要的,因为领域模型具有以下特点: 1.领域模型是对具有某个边界的领域的一个抽象,反映了领域内用户业务需求的本质;领 域模型是有边界的,只反应了我们在领域内所关注的部分; 2.领域模型只反映业务,和任何技术实现无关;领域模型不仅能反映领域中的一些实体概 念,如货物,书本,应聘记录,地址,等;还能反映领域中的一些过程概念,如资金转 账,等; 3.领域模型确保了我们的软件的业务逻辑都在一个模型中,都在一个地方;这样对提高软 件的可维护性,业务可理解性以及可重用性方面都有很好的帮助; 4.领域模型能够帮助开发人员相对平滑地将领域知识转化为软件构造; 5.领域模型贯穿软件分析、设计,以及开发的整个过程;领域专家、设计人员、开发人员 通过领域模型进行交流,彼此共享知识与信息;因为大家面向的都是同一个模型,所以 可以防止需求走样,可以让软件设计开发人员做出来的软件真正满足需求; 6.要建立正确的领域模型并不简单,需要领域专家、设计、开发人员积极沟通共同努力, 然后才能使大家对领域的认识不断深入,从而不断细化和完善领域模型; 7.为了让领域模型看的见,我们需要用一些方法来表示它;图是表达领域模型最常用的方 式,但不是唯一的表达方式,代码或文字描述也能表达领域模型; 8.领域模型是整个软件的核心,是软件中最有价值和最具竞争力的部分;设计足够精良且 符合业务需求的领域模型能够更快速的响应需求变化; 领域通用语言(UBIQUITOUS LANGUAGE) 我们认识到由软件专家和领域专家通力合作开发出一个领域的模型是绝对需要的,但是,那种方法通常会由于一些基础交流的障碍而存在难点。开发人员满脑子都是类、方法、算法、模式、架构,等等,总是想将实际生活中的概念和程序工件进行对应。他们希望看到要建立哪些对象类,要如何对对象类之间的关系建模。他们会习惯按照封装、继承、多态等面向对象编程中的概念去思考,会随时随地这样交谈,这对他们来说这太正常不过了,开发人员就是开发人员。但是领域专家通常对这一无所知,他们对软件类库、框架、持久化甚至数据库没有什么概念。他们只了解他们特有的领域专业技能。比如,在空中交通监控样例中,领域专家知道飞机、路线、海拔、经度、纬度,知道飞机偏离了正常路线,知道飞机的发射。他们用他们自己的术语讨论这些事情,

《领域驱动设计》基础知识汇总

《领域驱动设计》基础知识汇总(转) 1. 什么是领域(Domain) 我们所做的软件系统的目的都是来解决一系列问题,例如做一个电商系统来在线销售自己 企业的产品;做一个灰度发布平台来提升服务的质量和稳定性。任何一个系统都会属于某 个特定的领域,例如: ?论坛是一个领域:要做一个论坛,那这个论坛的核心业务是确定的:比如用户发帖、回 帖等核心基本功能; ?电商系统是一个领域:只要是电商领域的系统,那核心业务就是:商品浏览、购物车、 下单、减库存、付款交易等核心环节; 同一个领域的系统都具有相同的核心业务,因为他们要解决的问题的本质是类似的。因此 可以推断:一个领域本质上可以理解为一个问题域。只要确定了系统所属的领域,那么这个系统的核心业务,即要解决的关键问题就基本确定了。通常我们说,要成为一个领域的 专家,必须要在这个领域深入研究很多年才行,只有这样才会遇到非常多的该领域的问题,积累了丰富的经验。 2.界限上下文(Bounded Context) 通常来说,一个领域有且只有一个核心问题,我们称之为该领域的『核心子域』。在核心 子域、通用子域、支撑子域梳理的同时,会定义出子域中的『限界上下文』及其关系,用 它来阐述子域之间的关系。界限上下文可以简单理解成一个子系统或组件模块。 例如:下图是对酒店管理的子域和界限上下文的梳理:

3. 领域模型(Domain Model) 领域驱动设计(Domain-Driven Design)分为两个阶段: 1.以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交 流的过程中发现领域概念,然后将这些概念设计成一个领域模型; 2.由领域模型驱动软件设计,用代码来实现该领域模型; 由此可见,领域驱动设计的核心是建立正确的领域模型。领域模型具有以下特点: 1.对具有某个边界的领域的一个抽象,反映了领域内用户业务需求的本质。它属于『解 决问题空间』。领域模型是有边界的,只反应了我们在领域内所关注的部分,包括实体概 念(如:货物,书本,应聘记录,地址等),以及过程概念(如:资金转账等); 2.提高软件的可维护性,业务可理解性以及可重用性。领域模型确保了我们的软件的业 务逻辑都在一个模型中,帮助开发人员相对平滑地将领域知识转化为软件构造; 3.贯穿软件分析、设计、开发的整个过程。领域专家、设计人员、开发人员面向同一个 模型进行交流,彼此共享知识与信息,所以可以防止需求走样,让软件开发人员做出来的 软件真正满足需求;要建立正确的领域模型并不简单,需要领域专家、设计、开发人员积 极沟通共同努力,然后才能使大家对领域的认识不断深入,从而不断细化和完善领域模型; 4.为了让领域模型看的见,使用的常用表达领域模型的方式:图、代码或文字; 5.重要性:领域模型是整个软件的核心,是软件中最有价值和最具竞争力的部分;设计足 够精良且符合业务需求的领域模型能够更快速的响应需求变化; 4. 领域通用语言 由软件专家和领域专家合作开发一个领域的模型是有必要的。开发过程中,开发人员以类、算法、设计模式、架构等进行思考与交流。但领域专家对此一无所知,他们对技术上的术 语没有太多概念,只了解特有的领域专业技能,例如:在空中交通监控样例中,领域专家 知道飞机、路线、海拔、经度、纬度,他们有自己的术语来讨论这些事情。软件专家和领 域专家交流过程中,需要做翻译才能让对方理解这些概念。 领域驱动设计的一个核心原则是使用一种基于模型的语言。使用模型作为语言的核心骨架,要求团队在进行所有的交流是都使用一致的语言,在代码中也是这样,这种语言被称为 『通用语言』 5.建模思考的问题:用户需求 『用户需求』不能等同于『用户』,捕捉『用户心中的模型』也不能等同于『以用户为核 心设计领域模型』。设计领域模型时不能以用户为出发点去思考问题,不能老想着用户会 对系统做什么;而应该从一个客观的角度,根据用户需求挖掘出领域内的相关事物,思考 这些事物的本质关联及其变化规律作为出发点去思考问题。 领域模型是排除了人之外的客观世界模型,包含了人所扮演的参与者角色。但是一般情 况下不要让参与者角色在领域模型中占据主要位置,否则各个系统的领域模型将变得没有 差别,因为软件系统就是一个人机交互的系统,都是以人为主的活动记录或跟踪。例如:?论坛中如果以人为主导,那么领域模型就是:人发帖,人回帖,人结贴,等等; ?货物托运系统中如果以人为主导,就变成了:托运人托运货物,收货人收货物,付款人 付款,等等;

领域驱动设计和开发实战

领域驱动设计和开发实战 背景 领域驱动设计(DDD)的中心内容是如何将业务领域概念映射到软件工件中。大部分关于此主题的著作和文章都以Eric Evans的书《领域驱动设计》为基础,主要从概念和设计的角度探讨领域建模和设计情况。这些著作讨论实体、值对象、服务等DDD的主要内容,或者谈论通用语言、界定的上下文(Bounded Context)和防护层(Anti-Corruption Layer)这些的概念。 本文旨在从实践的角度探讨领域建模和设计,涉及如何着手处理领域模型并实际地实现它。我们将着眼于技术主管和架极师在实现过程中能用到的指导方针、最佳实践、框架及工具。领域驱动设计和开发也受一些架极、设计、实现方面的影响,比如: ?业务规则 ?持久化 ?缓存 ?事务管理 ?安全 ?代码生成 ?测试驱动开发 ?重构 本文讨论这些不同的因素在项目实施的整个生命周期中怎样对其产生影响,还有架极师在实现成功的DDD中应该去寻求什么。我会先列出领域模型应该具备的典型特征,以及何时在企业中使用领域模型(相对于根本不使用领域模型,或使用贫血的领域模型来说)。 文章包括一个贷款处理示例应用,来演示如何将设计立场、以及这里讨论的开发最佳实践,应用在真实的领域驱动开发项目之中。示例应用用了一些框架去实现贷款处理领域模型,比如Spring、Dozer、Spring Security、JAXB、Arid POJOs和Spring Dynamic Modules。示例代码用Java编写,但对大多数开发人员来说,不论语言背景如何,代码都是很容易理解的。 引言 领域模型带来了一些好处,其中有: ?有助于团队创建一个业务部门与IT部门都能理解的通用模型,并用该模型来沟通业务需求、数据实体、过程模型。 ?模型是模块化、可扩展、易于维护的,同时设计还反映了业务模型。 ?提高了业务领域对象的可重用性和可测性。 反过来,如果IT团队在开发大中型企业软件应用时不遵循领域模型方法,我们看看会发生些什么。 不投放资源去建立和开发领域模型,会导致应用架极出现“肥服务层”和“贫血的领域模型”,在这样的架极中,外观类(通常是无状态会话Bean)开始积聚越来越多的业务逻辑,而领域对象则成为只有getter和setter方法的数据载体。这种做法还会导致领域特定业务逻辑和规则散布于多个的外观类中(有些情况下还会出现重复的逻辑)。

在https://www.360docs.net/doc/345784230.html,MVC4中使用领域驱动设计

在领域驱动设计中,我们首先会为领域设计模型,且在设计的过程中完全不考虑存储和具体的实现细节。也就是说在设计中,我们把数据库放在了一个次要的位置(其实仍然很重要,只是在设计架构时我们不考虑它)。有了模型以后,下一步就是如何持久化(保存数据),且这里就存在着面向对象方式表示的数据和数据库所使用的基于元组的关系模型之间的不一致(对象-关系阻抗失谐)。如果可以选用面向对象数据库,事情就会容易许多,然而面向对象数据库并没有成为IT界的主流,因此关系型数据库就成为你唯一的选择。之所以会出现基于领域的设计是为了处理真实世界中的复杂性。运用领域驱动设计之后,你要么选用面向对像数据库,要么引入一个O/R映射层。 然而实现领域驱动设计很复杂,甚至可以说以个人之力完全无法实现。幸好现在有很多框架可用,例如Entity Framework(以下简称EF)。使用EF有三种方法:1.数据库优先,即先设计数据库,然后做数据库和面向对象模型的映射;2.模型优先,先用EF自带的设计工具设计模型,然后生成sql脚本,创建数据库;3.代码优先,先使用其他UML工具设计模型,根据模型手动编写模型代码,然后生成sql脚本,创建数据库。目前最流行的是代码优先,因为它最灵活,然而代码优先的工作量很大。而数据库优先的方法和领域驱动设计的思想相悖。所以我选择了模型优先的方法,但在EF4中,使用模型优先是有问题的,它生成的模型都继承自一个名为EntityObject的基类,这个基类包含了访问数据库的方法,这就不支持持久化透明了。幸好在EF4.1以后微软引入了DbContext,用EF4.1的模型优先可以生成支持持久化透明的实体类,不继承任何基类,数据访问由DbContext实现。在VS2012中创建一个https://www.360docs.net/doc/345784230.html, MVC4项目,VS2012会自动添加EF5.0的引用,并且在设计模型时会自动生成支持持久化透明的实体类,但在VS2010中要麻烦点,这里不做说明了,因为用了VS2012就完全没有问题了。具体建模过程不做介绍,网上一搜一大堆。下图为模型的一部分: 在传统的三层架构设计中,三层架构分为数据访问层、业务逻辑层和表现层。很多人在自己实现三层架构的时候都会明确的定义DAL、BLL和UI,但在实现的过程中总会有一些误解,例如很多人误把用户操作的流程当成业务逻辑,而数据访问层就是大量的sql语句和连接数据库的操作。实际上,用户的操作流程应该称为应用逻辑,应该放在服务层。我看过很多人设计的三层架构,BLL层几乎没有什么代码,只是简单的对DAL层的调用,复杂的数据访

基于事件驱动的DDD领域驱动设计框架分享(附源代码)

基于事件驱动的DDD领域驱动设计框架分享(附源代码) 补充:现在再回过头来看这篇文章,感觉当初自己偏激了,呵呵。不过没有以前的我,怎么会有现在的我和现在的enode框架呢?发现自己进步了真好!从去年10月份开始,学了几个月的领域驱动设计(Domain Driven Design,简称DDD)。主要是学习领域驱动设计之父Eric Evans的名著:《Domain-driven design:领域驱动设计:软件核心复杂性应对之道》,以及另外一本Martin Flower的《企业应用架构模式》,学习到了不少关于如何组织业务逻辑方面的知识。另外,在这个过程中也接触到了一些开源的架构和一些很好的思想。如:命令查询职责分离(Command Query Responsibility Segregation,简称CQRS),事件驱动架构(Event Driven Architecture,简称EDA),以及四色原型和DCI架构,等等。前面这些知识对我来说是非常宝贵的财富,可以说我能进淘宝,很大程度上也是因为我学习了前面这些知识的原因。在介绍我设计的框架之前,我想先探讨一下以往我们都是如何思考设计OO的系统的。大家都知道,真正的对象应该是不仅有属性,而且有行为的。并且大家也有另外一个共识,那就是为了完成某个任务,各个对象应该会相互协作共同完成这个任务。之前我们在设计一个系统时,往往会先设计好各个对象,明确他们的职责,在这个过程中,

还会考虑如何建立对象之间的关系(依赖、关联、聚合、组合),在这些关系的影响下,我们会认为对象之间应该有主从关系、依赖关系,等等。然后我们所做的这些设计最终的目的是为了能让对象之间能够通过相互协作来共同完成某 个任务。这种方式最核心的设计特色是,我们会通过”对象引用“的方式来实现对象之间的各种关系。这种方式很好,并且我们也已经完全习惯了从对象的职责以及它们之间的关系 的角度去设计对象。但这仅仅体现了一个哲学思想,那就是“物体之间通过直接作用完成某个任务”。我觉得任何两个对象之间的交互有两种形式:1)直接作用,即对象A引用一个对象B,然后A调用B提供的某个方法,以此来完成两个对象之间的协作;2)间接作用,对象A不引用对象B,仅仅包含了一个对象B的唯一标识,当它要和对象B协作时,会发送一个消息给对象B,然后对象B收到该消息后做出响应,从而实现两个对象之间的协作;不管是哪种方式,他们最终的效果是一致的,都可以实现两个对象之间的交互并最终完成某个任务。那么这两种方式各自的优缺点在哪里呢?我个人觉得对于对象引用的方式,其好处就是简单、直观、容易理解,很符合我们平时的设计习惯。但坏处是什么呢?我个人觉得这种方式是形成对象耦合的根本原因,对象A对对象B存在了紧密的耦合,也许你会说,在间接作用的方式下,对象A不也会保留一个对象B的唯一标识吗?没错,但

领域驱动设计和实践

领域驱动设计和实践 引言 软件系统面向对象的设计思想可谓历史悠久,20世纪70年代的Smalltalk 可以说是面向对象语言的经典,直到今天我们依然将这门语言视为面向对象语言的基础。随着编程语言和技术的发展,各种语言特性层出不穷,面向对象是大部分语言的一个基本特性,像C++、Java、C#这样的静态语言,Ruby、Python 这样的动态语言都是面向对象的语言。 但是面向对象语言并不是银弹,如果开发人员认为使用面向对象语言写出来的程度本身就是面向对象的,那就大错特错了。实际开发中,大量的业务逻辑堆积在一个巨型类中的例子屡见不鲜,代码的复用性和扩展性无法得到保证。为了解决这样的问题,领域驱动设计提出了清晰的分层架构和领域对象的概念,让面向对象的分析和设计进入了一个新的阶段,对企业级软件开发起到了巨大的推动作用。 本文主要介绍了领域驱动设计的基本概念、要素、特点,对比了事务脚本和领域模型的特点,最后介绍了我们在软件开发过程中的领域驱动设计实践。 什么是领域驱动设计(DDD) 领域驱动设计事实上是针对OOAD的一个扩展和延伸,DDD基于面向对象分析与设计技术,对技术架构进行了分层规划,同时对每个类进行了策略和类型的划分。 领域模型是领域驱动的核心。采用DDD的设计思想,业务逻辑不再集中在几个大型的类上,而是由大量相对小的领域对象(类)组成,这些类具备自己的状态和行为,每个类是相对完整的独立体,并与现实领域的业务对象映射。领域模型就是由这样许多的细粒度的类组成。基于领域驱动的设计,保证了系统的可维护性、扩展性和复用性,在处理复杂业务逻辑方面有着先天的优势。 领域驱动设计的特点

相关主题
相关文档
最新文档