代码改变世界

关于领域驱动设计与面向数据库设计

2011-09-07 17:44  熬夜的虫子  阅读(1888)  评论(1编辑  收藏  举报

╮(╯▽╰)╭ 开发时间越长越觉得自己的知识储备不够  本篇文章只代表虫子个人观点 欢迎大牛们吐槽

首先,虫子不会说哪一种更优秀,而是说对于新给的需求适合哪种设计。更贴切的一点,对于一个大型的系统应用应该兼容2种设计思想。分2个阶段,首先在需求确认阶段利用领域驱动建模,细化模块、角色、关系、行为以及资源等。建模不需要太彻底。然后、分块完毕后在概要设计阶段可以再切换设计思路,模块化的应用按照面向数据库的设计思想,这样在2个阶段都利用了2种设计思想的长度。最大程度的提高系统的价值。

 

下面来介绍下2种设计

1.先来扯扯领域驱动设计 借鉴下一些大牛的经验http://www.cnblogs.com/tsoukw/archive/2007/09/28/908983.html

系统真正的价值那就是﹕系统能为使用提供什么服务﹐以及提供的质量(即如何服务﹐这也是系统内部的我们要做的事情)。系统之间本质的区别应该不是用了什么语言﹐OO还是过程﹐用了什么数据库。因为这两个系统使用什么语言﹐采用什么方式﹐利用什么DBMS﹐都是不能本质区别这两个系统的价值的。

领域模型的价值不在于它的设计优美(它只是一些对象﹐最重要的也就是对象之间的关系)﹐而在于它体现了系统的核心价值。 

领域驱动设计实质上是一种由内而外的设计方法,俗话说的先中间(模型和服务)后两边(界面,数据库以及集成)。我的理解是领域驱动设计实质是业务场景和实体驱动的设计,有关注业务场景和流程,分析,识别和抽象业务对象,进一步分析对象间的创建,关联,逻辑和服务。注意领域模型和多层架构和技术关联很小,更多的是关注概念模型和业务逻辑,因此抛开了多层架构和框架本身,先研究领域模型再由内而外过渡到数据层和界面层,以及多层的集成。
通常将领域中的组成角色分为以下五种:

实体(Entity):拥有唯一标识的对象。
值对象(Value Object):没有唯一标识的对象。
工厂(Factory):定义创建实体的方法。
资源库(Repository):管理实体的集合并封装其持久化过程。
服务(Service):实现不能指派或封装在一个单一对象上的操作。

实体也就是业务对象,值对象是没有行为的,类似于结构体。工厂就是定义创建实体的方法。资源库的作用是管理实体的集合,并封装其持久化过程,这里面说明了资源库管理实体对象的全生命周期。服务简单点讲就是接口,在做领域分析的时候会发现有些领域很难映射到对象,拥有属性和暴露行为,这个时候就应该识别为服务。服务一个重要作用仍然是屏蔽领域逻辑内部复杂性,体现高内聚,松耦合的思想。

领域模型是一种思维﹐是一种方法,是在系统分析阶段使用﹐而不是程序员在自己的代码中进行纯设计时的工具。我们不是为了OO而领域﹐不是为了最终要新增数据库而领域﹐这也是为什么在没有理解领域模型本质时﹐使用它进行片断式的代码编写﹐得不到任何好处的原因。想想你在编码中弄出的那些用户﹐图书对象﹐它在系统中的位置是什么?您不能否认它就是为了让新增数据库时更方便吧?

领域模型的建立决不是像如何实现某些纯软件逻辑而进行的纯软件设计。(我这里提出的纯软件设计﹐指的是如何在设计中体现扩展性﹐灵活性﹐可维护性而进行的设计)。而是为了能够分析系统提供的服务而产生的一种思维结果。

系统分析员在接手一个系统后﹐首先要做到的事情就是得出系统的服务和服务场景。也就是我们经常所讲的用例(use case)

可惜的是﹐很多使用者一直将用例的作用和价值没弄清楚。我想如果没有真正理解用例的作用时﹐您的用例分析将会一直停留在和别人Demo系统之上﹐提供一個漂亮的圖形好說話而已﹐而不会对我们的系统开发有任何实质作用。

用例表示的是使用系统的一个场景﹐其本质在于详细描述了系统用户(actor)与系统是如何交互的﹐以及交互的后果是什么﹐详细而完善的用例将指导您进行系统开发的全过程。

 

2.再来看看面向数据库设计

以数据库为中心的开发方式﹐将所有业务逻辑都放在了数据库﹐并结合系统的代码来保证业务逻辑的实现。

数据库模式要面向应用系统﹐我们选择面向对象的系统设计也好,面向对象的数据库设计也好,根本目的是服务于应用系统的需要。

从某种意义上讲,是数据库设计的面向对象特征最终奠定了整个系统的面向对象性,才使面向对象方法在程序开发阶段全面开花。其效果归纳如下:

1. 数据库结构清晰,便于实现 OOP  由于实现了应用模块对象对数据库对象的完全映射,数据库逻辑模型可以自然且直接地模拟现实世界的实体关系。用户所处的当前物理世界、系统开发者所抽象的系统外部功能,与支持系统功能的内部数据库 (数据结构)一一对应,所以用户、开发者和数据库维护人员可以用一致的语言进行沟通。特别是对多数不了解业务的程序开发人员来说,这种将应用对象与相应的数据对象封装在对象统一体中的设计方法,大大减轻了程序实现的难度,使他们只要知道加工的数据及所需的操作即可,而且应用程序大多雷同,可以多处继承由设计人员抽象出来的、预先开发好的各种物理级超类。

2. 数据库对象具有独立性,便于维护  除了数据库表对象与应用模块对象一一对应外,在逻辑对象模型中我们没有设计多重继承的泛化关系,所以这样得到的数据库结构基本上是由父表类和子表类构成的树型层次结构,表类间很少有继承以外的复杂关系,是一个符合局部化原则的结构,从而使数据库表数据破坏的影响控制在局部范围且便于修复,给系统开通后的数据库日常维护工作带来便利。

3. 需求变更时程序与数据库重用率高,修改少  在映射应用对象时,除关系映射规范化后可能出现一对多的表映射外,大多数应用对象与表对象是一一对应的。我们可以把规范化处理后的、由一个应用对象映射出来的多个表看成一个数据库对象。因此当部分应用需求变更时,首先,系统修改可以不涉及需求不变更的部分。其次,变更部分的修改可以基本上只限于追加或删除程序模块或追加新库表,而基本上不必。