背景
使用DDD开发大概也有五个月的时间了,由于当时公司导师的推荐,第一次接触DDD领域驱动到现在彻底迷恋这种开发的模式,为其思想的奥妙所折服,一直以来,总想花一点时间来总结一下,正直光棍节(天猫狂欢购物节)当天,“静下心来”(PS:没有人民币)总结一下。
说起DDD不得不说一篇文章:http://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html
第一次接触,就是这篇文章,当时看起来晦涩难懂,后来慢慢的读起来,每一次都有精神的提升,网上也有很多关于DDD的介绍,这里将不会在介绍概念什么的,下边主要是自己工作过程中的一些总结。
如何快速入门
第一次接触DDD的时候,概念高深莫测,奥秘深不可见,大有不知所云的趋势,后来导师的引导,让直接从项目中直接入手,遂逐步揭开其一层层雾纱,如图1:
图片描述" title="" src="http://img.blog.csdn.net/20151111161131243">
DDD一般的分层结构和调用顺序如上所述,infrastructure是基础设施层,domain是领域层,application是应用层,facade和facade-impl是门面层(前者是门面接口层,后者是门面实现层),webapp是用户接口层(采用web形式)。
下边是一种项目的分层图,采用的Maven管理代码。图2:
图片描述" title="" src="http://img.blog.csdn.net/20151111175044036">
分层的介绍
1、web:首先包含网站前端,如果使用SpringMVC的话,还需要其Controler,
图片描述" title="" src="http://img.blog.csdn.net/20151111174956018">
该Controler层主要是用于接收HTTP请求和返回客户端,一般不进行逻辑上的判断,其代表了用户可以进行的操作,一般不涉及领域驱动的思想,示例代码:
@ResponseBody @RequestMapping(value="/create",method=RequestMethod.POST)publicStringcreate(AirlineWhiteListDTOairlineWhiteListDTO){ MDC.put(ConstString.TRACE_ID,LogUtil.getTraceId(ConstAirlineWhiteList.CREATE)); Responseresponse=airlineWhiteListFacade.create(airlineWhiteListDTO);returnsuper.handleResponse(response); }12345671234567
第一行使用MDC用于记录(打log)http请求的顺序和调用的方法,第二行调用“门面层”facede,获得Response返回对象,第三行用于判断是返回界面还是返回data等操作,即时SpringMVC的ModalAndView;
2、facade和facade-impl一个是门面层接口一个是门面层接口的实现类,示例代码:
@Autowired IAirlineWhiteListApplicationairlineWhiteListApplication;publicResponsecreate(AirlineWhiteListDTOairlineWhiteListDTO){Responseresponse=newResponse(); try{ AirlineWhiteListairlineWhiteList=AirlineWhiteListAssembler.toEntity(airlineWhiteListDTO); airlineWhiteListApplication.create(airlineWhiteList); }catch(Exceptione){response=newResponse(e); } returnresponse; }1234567891011121312345678910111213
可以看出这是在web的controller中访问的方法,主要进行数据的组装(实体对象和数据传输对象的转换),以及返回对象Response的转换。
之所以成为门面层,我们暂可认为是我们用户可以看到的整个系统的东西,例如上述中的Response就是返回给用户看的东西。
3、Application层,上述的facade调用到了application中的方法,
@InjectprivateAirlineWhiteListairlineWhiteList;publicbooleancreate(AirlineWhiteListairlineWhiteList){returnthis.airlineWhiteList.add(airlineWhiteList); }123456123456
这一层主要是操作实体对象的,是于数据更近一层的操作,主要定义了用户所拥有的方法和属性,操作实体对象层,将实体对象所有的方法展示出来供用户使用;
4、domain层,数据实体层,相比MVC中的modal简单的只是数据库的映射,这种“毫无灵魂”的对象,领域模型中不但有一个实体对象的属性还有其方法,(我们可以在实际使用的时候使用继承DTO的方式),在这一层中定义了实体对象操作数据库的方法;
这里我们的实体对象不仅是拥有属性还具有方法的,就像一个人一样,我们不但拥有做人的基本特征(两手、两脚等),我们还有属于自己的技能(方法),这样的话才是一个拥有灵魂的东西;
5、infra这一层包含了访问数据库的方法、数据仓储(sql、nosql、api)和一些工具类,service等;
由于是domain层调用该层的,实体对象的操作固然包含CRUD,既是我们需要进行对数据库的操作,当我们只有一个数据源的时候,很简单,但是后期项目中数据源可能会增加,可能会添加缓存等,这样的话使用原来的MVC模式的话,我们可能需要修改很多,如下图:
图片描述" title="" src="http://img.blog.csdn.net/20151111170536351">
但是使用DDD的话,由于我们的Domain调用的是infra 数据仓库Repository接口,Repository中定义了访问数据源的方法,这样的话,当我门新增数据源的时候,我们的Domain层以上都无需修改,只需进行infra层的修改即可。
图片描述" title="" src="http://img.blog.csdn.net/20151111172024787">
上图中有2个数据源,一个是sql一个是nosql,在方框中的Repository即调用的是nosql和sql中的方法,这样的话Domain直接调用Repository即可。
领域驱动的示例:
如果想快速的领回DDD的奥妙,这里有一个案例,一个很不错的开源系统,使用的正是DDD思想,可以把代码下载下来仔细研究,其中的思想是很不错、很不错的,地址如下:http://www.openkoala.org/
总结:
类比MVC“哑铃式”的分层结构中,Model和View代码少,Controller代码臃肿的布局格式,DDD拥有更多的分层,各层之间各司其职,协调工作,一步步调用,井然有序,对于后期的维护,只要是熟悉DDD的开发人员都可以很好的维护。
http://blog.csdn.net/xlgen157387/article/details/49782697