ddd分层感想
在传统的三层中,大家比较熟悉的更多是petshop的分层形式。
在其中使用Dao模式分离数据库,使用了Abstract Factory模式提供反射创建Dao中的持久实例。
很多人首次对ms在demo中使用设计模式感到欣慰,以为是ms看到.net方面要提高下设计模式的
能力。我想其中有一些这样的原因。是个人都知道,ms做什么都想入门简单。如果真的能解决那个问题
ms还愿意用Abstract Factory模式吗?这个问题就是循环依赖。ORM能解决。但是Abstract Factory相比ORM来说
还是AF简单的多了。然而许多人还美其名曰“依赖注入”,其实它那是没办法.如果不想循环依赖,那就不能在dao中使用model中的实体。
在大中型项目中,这样的做dao可以想象是场灾难。
下面唠叨下DDD中的分层
Infrastructure(最底层) 为上层提供通用的技术能力。
Domain在Infrastructure的上一层。
按照分层的基本原则:某一层中的所有元素只能依赖于同一层的其他元素或依赖其所有比它底的下层元素(Relaxed Layered Stystem)(Buschmann et al,1996)。
也就是说Domain可以引用Infrastructure,而Infrastructure不能引用Domain,这样就导致前面的问题
领域实体到了Infrastructure就被打散成基本元素(这里没有使用ORM)。Infrastructure跟其他层也是同样的
问题。数据的封装到了Infrastructure中显得那么别扭。ddd的分层可能出现了问题。应该不是,在ddd全书中
都是使用ORM做底层,所以很少出现这样的情况。也就是说我们始终需要一个Meta Mapping Layer(元数据映射层)。
在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.
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.
且看Jimmy Nilsson把ddd分层改为
这样的改变,我认为不妥。图中为了不造成循环依赖,可以使用Abstract Factory提供反射创建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.
这个问题,不仅仅只在infrastructure 和Domain之间存在,而是在层之间都存在。
因为分层的原则,所有设计的依赖就必须是单向的,如果下层要调用上层的对象,问题就出现了。
在ddd书中也提到了,使用回调或Observer模式可以解决。
如果不使用MVC,在infrastructure 和Domain之间也许只能提供Meta Mapping Layer才能解决问题。
总结说明下,我认为ddd中的分层没有问题。只是传统的dao要使用ddd不方便罢了。