ddd心得

注意点:
一、应该只为聚合根提供一个仓储,推论:访问的起点是根,根内部对象添加删除更新问题(有一些框架能解决,这里的存储并不一定是关系数据库).聚合的出现是为了减少对象间的关联,聚合的选择应该是在导航与查询之间做选择。

二、Infrastructure做为ddd层次的最底层,绝对不能违反分层的基本原则,为了在Infrastructure中使用
Domain中的对象而让Infrastructure去引用Domain.解决办法:元数据映射
在此指出:Jimmy Nilsson的Applying Domain-Driven Design and Patterns: With Examples in C# and .NET这本书中
Another difference is that instead of all calls going down, the Infrastructure layer might "know" about the Domain layer and might create instances there when reconstituting from persistence. The point is that the Domain Model should be oblivious of the infrastructure."
我认为这样不妥,明显违反分层原则。

今天(2008-7-11),在看houghtWork公司写的《Pragmatic.Bookshelf.The.ThoughtWorks.Anthology》书的时候,惊奇的发现,Erik也在讨论这个问题,不过里面只是简单的提了下,如下:
Erik considers a similar problem. In a well-designed system,
you decouple the domain model from infrastructure layers, but this
requires that the infrastructure layer use the metadata present in the
domain model. Some implicit metadata can be gleaned from what’s in
there such as the choice of classes to represent certain domain elements,
but it doesn’t really provide enough information for really rich
stuff like validations. Some modern languages such as Java and C#
provide for more metadata in the form annotations and attributes, and
Erik explores how to exploit these features through a case study.
看我上篇讨论:http://www.cnblogs.com/bmrxntfj/archive/2008/07/08/1237968.html

三、作为第二条的推论,一些基类、接口比如:IEntity,应该放在Infrastructure中,这也符合ddd书中的分层图。
然而,有时框架提供了太多技术性解决方案反而会干扰领域模型,比如:entity beans.这个在ddd书中也有提及。
这里.NET Domain-Driven Design with C#: Problem-Design-Solution书的作者Tim也讨论了这点。
http://www.codeplex.com/dddpds/Thread/View.aspx?ThreadId=30532

四、Application不是Domain的外观,所以通常情况可以直接使用Domain,而不是再在Appliction中再封装,这也不符合ddd的分层。
Jimmy Nilsson的Applying Domain-Driven Design and Patterns: With Examples in C# and .NET这本书中
"I think there are few things to note regarding how I use layering now compared to my old style. First of all, the Application layer isn't mandatory; it is only there if it really adds value. Since my Domain layer is so much richer than before, it's often not interesting with the Application layer."

五、仓储应该是internal访问,客户应该使用Service.不应使用Repository.

六、“规则,过滤”这些不能把他们直接写到Service中,比如:if什么什么,然后entity.什么。这里就应该把隐式概念转化为显示概念。定义出那个规则。虽然领域层服务控制了领域模型,但是不代表业务核心就要放入领域层服务,而应该放入领域模型中.
这个jdon也有过讨论。
http://www.jdon.com/article/33948.html
http://www.jdon.com/jivejdon/thread/34321.html

七、不变量的检查。

ddd书中讨论过,认为应该放在工厂中,有时也会放在聚合根中。首先应该明确的是我们已经显示定义出了该规则对象,

也就是说在工厂中创建完后,我们就应该检查一下,但是传进工厂的通常仅是事物本质的属性或标识。有一些属性需要后续添加,也就是说会有可能违反不变量,ddd书中建议对属性赋值时检查,这确实能解决,但是这样就导致了一个规则被重复定义。另外有些人可能会在持久化调用服务时检查,但是不要忘了如果客户没有持久化,就去用它参与逻辑计算,这样一来程序必然出错。

另外一个复杂的问题就是对象的重建,重建也需要不变量检查,如果检查通不过,还需要修复,ddd书中也没有具体方法,这种修复是系统内部处理,还是提示给客户,由客户来处理,显然应该提示给客户,但是这样做非常复杂,可能需要一个框架的支撑,这里重建的不变量检查也应该放在工厂中来处理。

不变量的检查是否有更好的方法,还是我的理解有错?

八、模块的划分应该按业务来,而不是按领域模式来划分。

九、关联,根据第一条,聚合的内部对象应该从聚合根开始访问,聚合间的访问,可以通过服务获得。
十、以领域模型为中心
在领域模型内的数据、成员,领域模型绝对信任,来自外界的一概不信任。主要表现在创建和重建(从持久层获取数据)时,也就时工厂的职责
工厂必须保证实体的不变量和完整性。创建比较容易处理(抛异常,或返回null),这个大多数程序都做类似处理。但是对于重建都不处理,或者根本就没想过要处理,因为它信任来自持久层的数据。对于重建的处理非常复杂,简单的做法就是记录日志,复杂的需要一个框架来支持
最好的方式是提示给客户,然后按向导完成数据修复,有时也可以系统处理(这个跟收藏夹的弊端一样)
十一、命名
这点无论使用什么方法论,命名都是至关重要的,它关系到你对领域的理解。
持续更新......
如有不对的地方,还望指正。

posted on 2008-07-09 17:33 bmrxntfj 阅读(...) 评论(...) 编辑 收藏

公告

统计

  • 随笔 - 24
  • 文章 - 0
  • 评论 - 67