DDD领域驱动模型设计

背景

使用DDD开发大概也有五个月的时间了,由于当时公司导师的推荐,第一次接触DDD领域驱动到现在彻底迷恋这种开发的模式,为其思想的奥妙所折服,一直以来,总想花一点时间来总结一下,正直光棍节(天猫狂欢购物节)当天,“静下心来”(PS:没有人民币)总结一下。

说起DDD不得不说一篇文章:http://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html

第一次接触,就是这篇文章,当时看起来晦涩难懂,后来慢慢的读起来,每一次都有精神的提升,网上也有很多关于DDD的介绍,这里将不会在介绍概念什么的,下边主要是自己工作过程中的一些总结。

如何快速入门

第一次接触DDD的时候,概念高深莫测,奥秘深不可见,大有不知所云的趋势,后来导师的引导,让直接从项目中直接入手,遂逐步揭开其一层层雾纱,如图1:

DDD一般的分层结构和调用顺序如上所述,infrastructure是基础设施层,domain是领域层,application是应用层,facade和facade-impl是门面层(前者是门面接口层,后者是门面实现层),webapp是用户接口层(采用web形式)。

下边是一种项目的分层图,采用的Maven管理代码。图2:

分层的介绍

1、web:首先包含网站前端,如果使用SpringMVC的话,还需要其Controler,

该Controler层主要是用于接收HTTP请求和返回客户端,一般不进行逻辑上的判断,其代表了用户可以进行的操作,一般不涉及领域驱动的思想,示例代码:

@ResponseBody
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public String create(AirlineWhiteListDTO airlineWhiteListDTO) {
        MDC.put(ConstString.TRACE_ID, LogUtil.getTraceId(ConstAirlineWhiteList.CREATE));
        Response response = airlineWhiteListFacade.create(airlineWhiteListDTO);
        return super.handleResponse(response);
    }

第一行使用MDC用于记录(打log)http请求的顺序和调用的方法,第二行调用“门面层”facede,获得Response返回对象,第三行用于判断是返回界面还是返回data等操作,即时SpringMVC的ModalAndView;

2、facade和facade-impl一个是门面层接口一个是门面层接口的实现类,示例代码:

@Autowired
IAirlineWhiteListApplication airlineWhiteListApplication;

public Response create(AirlineWhiteListDTO airlineWhiteListDTO) {
        Response response = new Response();
        try {
            AirlineWhiteList airlineWhiteList = AirlineWhiteListAssembler.toEntity(airlineWhiteListDTO);
            airlineWhiteListApplication.create(airlineWhiteList);
        } catch (Exception e) {
            response = new Response(e);
        }
        return response;
    }

可以看出这是在web的controller中访问的方法,主要进行数据的组装(实体对象和数据传输对象的转换),以及返回对象Response的转换。

之所以成为门面层,我们暂可认为是我们用户可以看到的整个系统的东西,例如上述中的Response就是返回给用户看的东西。

3、Application层,上述的facade调用到了application中的方法,

@Inject
private AirlineWhiteList airlineWhiteList;

public boolean create(AirlineWhiteList airlineWhiteList) {
        return this.airlineWhiteList.add(airlineWhiteList);
    }

这一层主要是操作实体对象的,是于数据更近一层的操作,主要定义了用户所拥有的方法和属性,操作实体对象层,将实体对象所有的方法展示出来供用户使用;

4、domain层,数据实体层,相比MVC中的modal简单的只是数据库的映射,这种“毫无灵魂”的对象,领域模型中不但有一个实体对象的属性还有其方法,(我们可以在实际使用的时候使用继承DTO的方式),在这一层中定义了实体对象操作数据库的方法;

这里我们的实体对象不仅是拥有属性还具有方法的,就像一个人一样,我们不但拥有做人的基本特征(两手、两脚等),我们还有属于自己的技能(方法),这样的话才是一个拥有灵魂的东西;

5、infra这一层包含了访问数据库的方法、数据仓储(sql、nosql、api)和一些工具类,service等;

由于是domain层调用该层的,实体对象的操作固然包含CRUD,既是我们需要进行对数据库的操作,当我们只有一个数据源的时候,很简单,但是后期项目中数据源可能会增加,可能会添加缓存等,这样的话使用原来的MVC模式的话,我们可能需要修改很多,如下图:

但是使用DDD的话,由于我们的Domain调用的是infra 数据仓库Repository接口,Repository中定义了访问数据源的方法,这样的话,当我门新增数据源的时候,我们的Domain层以上都无需修改,只需进行infra层的修改即可。

上图中有2个数据源,一个是sql一个是nosql,在方框中的Repository即调用的是nosql和sql中的方法,这样的话Domain直接调用Repository即可。

领域驱动的示例:

如果想快速的领回DDD的奥妙,这里有一个案例,一个很不错的开源系统,使用的正是DDD思想,可以把代码下载下来仔细研究,其中的思想是很不错、很不错的,地址如下:http://www.openkoala.org/

总结:

类比MVC“哑铃式”的分层结构中,Model和View代码少,Controller代码臃肿的布局格式,DDD拥有更多的分层,各层之间各司其职,协调工作,一步步调用,井然有序,对于后期的维护,只要是熟悉DDD的开发人员都可以很好的维护。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 05:10:57

DDD领域驱动模型设计的相关文章

(转载)浅谈我对DDD领域驱动设计的理解

原文地址:http://www.cnblogs.com/netfocus/p/5548025.html 从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品.所以,自然而然就想到要做一个普通电商系统,用于实现在线销售自己企业产品的目的. 再比如,我是一家互联网公司,公司有很多系统对外提供服务,面向很多客户端设备.但是最近由于各种原因,导致服务经常出故

浅谈我对DDD领域驱动设计的理解

从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品.所以,自然而然就想到要做一个普通电商系统,用于实现在线销售自己企业产品的目的. 再比如,我是一家互联网公司,公司有很多系统对外提供服务,面向很多客户端设备.但是最近由于各种原因,导致服务经常出故障.所以,我们希望通过各种措施提高服务的质量和稳定性.其中的一个措施就是希望能做一个灰度发布的平台,这个

WCF客户端配置以及代理-----基于DDD领域驱动设计的WCF+EF+WPF分层框架(4)

写在最前面:转载请注明出处 目录置顶: 关于项目--------------------基于DDD领域驱动设计的WCF+EF+WPF分层框架(1) 架构搭建--------------------基于DDD领域驱动设计的WCF+EF+WPF分层框架(2) WCF服务端具体实现---------基于DDD领域驱动设计的WCF+EF+WPF分层框架(3) WCF客户端配置以及代理-----基于DDD领域驱动设计的WCF+EF+WPF分层框架(4) Domain具体实现------------基于DD

DDD领域驱动设计之领域服务

1.DDD领域驱动设计实践篇之如何提取模型 2.DDD领域驱动设计之聚合.实体.值对象 3.DDD领域驱动设计之领域基础设施层 什么是领域服务,DDD书中是说,有些类或者方法,放实体A也不好,放实体B也不好,因为很可能会涉及多个实体或者聚合的交互(也可能是多个相同类型的实体),此时就应该吧这些代码放到领域服务中,领域服务其实就跟传统三层的BLL很相似,只有方法没有属性,也就没有状态,而且最好是用动词命名,service为后缀,但是真正到了实践的时候,很多时候是很难区分是领域实体本身实现还是用领域

DDD领域驱动设计之聚合、实体、值对象

关于具体需求,请看前面的博文:DDD领域驱动设计实践篇之如何提取模型,下面是具体的实体.聚合.值对象的代码,不想多说什么是实体.聚合等概念,相信理论的东西大家已经知晓了.本人对DDD表示好奇,没有在真正项目实践过,甚至也没有看过真正的DDD实践的项目源码,处于极度纠结状态,甚至无法自拔,所以告诫DDD爱好者们,如果要在项目里面实践DDD,除非你对实体建模和领域职责非常了解(很多时候会纠结一些逻辑放哪里好,属于设计问题)以及你的团队水平都比较高认同DDD,否则请慎重...勿喷! 代码在后,请先看D

DDD领域驱动设计之领域基础设施层

1.DDD领域驱动设计实践篇之如何提取模型 2.DDD领域驱动设计之聚合.实体.值对象 其实这里说的基础设施层只是领域层的一些接口和基类而已,没有其他的如日子工具等代码,仅仅是为了说明领域层的一些基础问题 1.领域事件简单实现代码,都是来至ASP.NET设计模式书中的代码 namespace DDD.Infrastructure.Domain.Events { public interface IDomainEvent { } } namespace DDD.Infrastructure.Dom

DDD领域驱动设计仓储Repository

DDD领域驱动设计初探(二):仓储Repository(上) 前言:上篇介绍了DDD设计Demo里面的聚合划分以及实体和聚合根的设计,这章继续来说说DDD里面最具争议的话题之一的仓储Repository,为什么Repository会有这么大的争议,博主认为主要原因无非以下两点:一是Repository的真实意图没有理解清楚,导致设计的紊乱,随着项目的横向和纵向扩展,到最后越来越难维护:二是赶时髦的为了“模式”而“模式”,仓储并非适用于所有项目,这就像没有任何一种架构能解决所有的设计难题一样.本篇

DDD领域驱动设计实践篇之如何提取模型

需求说明: 省级用户可以登记国家指标 省级用户和市级用户可以登记指标分解 登记国家指标时,需要录入以下数据:指标批次.文号.面积,这里省略其他数据,下同 登记指标分解时,需要录入以下数据:指标批次.文号.面积,以及可以选择多个市(市级登记的时候是县)的指标,每个市(县)的指标也是要输入批次.文号.面积 登记指标分解时,一个指标批次不能选择多个相同的市(县) 登记指标分解时,需要判断当前剩余面积是否足够,比如省登记的时候,要看国家本年度下发给省的指标面积是否大于省本年度所以指标面积,登记国家指标不

看领域驱动模型设计有感

最近在看<领域驱动模型设计>这本书,对自己所看所想就边看边记了. 看了这本书的前三章,对领域驱动模型的核心,我认为领域驱动模型必须关心的是:模型的设计分析必须和代码实现结合.对于没有结合实现的领域模型是没有价值.这也就对领域模型的建立有了一个约束:不能只是设计人员和领域专家在一起对他们所关心的问题域进行讨论.分析,最终确立模型,还必须让开发人员也参与进来,分析确立的模型能否实现以及实现难易程度.最终确定一个项目需要.可以用代码真实反映的模型.这样的模型才能映射到代码实现,同样具体的代码也就可以