代码改变世界

我对DDD的认知(一)

2011-04-07 12:00  Virus-BeautyCode  阅读(5442)  评论(17编辑  收藏

1 引言

DDD,全名:Domain Driven Design,中文名:领域驱动设计。

2 DDD的分层

分层的架构方式是我们常用的,这里的分层是说n-layer,指的是逻辑的分层,目的是分离职责。常用的是三层:表现层,业务逻辑层,数据访问层。

DDD把原来经典三层(表现层,业务逻辑层,数据访问层)中的业务逻辑层又细分为两层:应用层和领域层。应用层负责领域对象的协调和调度,领域层包含具体的领域对象,领域规则(也就是业务规则),更大限度的实现业务规则的重用和职责的分离。将数据访问层并入基础架构层。变成了四层:

  1. Presentation
  2. Application
  3. Domain
  4. Infrastructure。

3 DDD的持久化设计

3.1 三层中的持久化设计

三层模式中的数据持久化是由数据访问层负责的,是至下而上的服务。为什么说是至下而上的呢?因为我们会写下面的代码。

public class Product
   {
       public Guid Id { get; set; }
       public string Name { get; set; }
       public List<Parameter> Parameters { get; set; }
       public List<Delivery> Deliverys { get; set; }
       public List<Image> Images { get; set; }
   }

   public class Parameter
   {
   }
   public class Delivery
   { }
   public class Image
   { }

   public class ProductDAL
   {
       public bool Add(Product product);
       public bool Update(Product product);
       public bool Delete(Product product);
       public Product Get(Guid id);
       public List<Product> FindAll();
   }

 

在数据访问层会写上所有针对这个Product的操作,不管需要与否,有时候干脆每张表一个DAL,用工具生成实体和数据访问类,这下数据访问层就完成了,后面可能会根据需要进行修改。管它业务层是否需要呢,反正需要的我都有了,不需要的我也有了,自己组合吧。

这种情况会造成代码浪费,甚至是大量的数据访问代码根本就没有用过。最重要的是也没有根据上层的需求来完成持久化的任务,而是简单的完成了表的增删改查,反正实现业务你就组合吧。总有一种组合会实现你的业务。这也就怪不得别人叫我们增删改查程序员了,因为如果业务简单,正好大部分业务都很简单,那么业务层就就剩下

new ProductDAL().Add(new Product());

这么一句了。

 

3.2 DDD的持久化设计

在DDD中,持久化被放在了基础架构层中。基础架构层不仅包括数据持久化,而且包括基础类库,Cross-Cutting等工具。DDD的持久化是至上而下的,是根据DDD的需要进行持久化。持久化的对象也变成了领域对象,而不再是单个表对象。

在领域层定义持久化的接口,持久化的对象是业务对象或者领域对象。在基础架构层实现领域层需要的持久化接口,具体的实现将领域对象持久化到数据存储中,是数据库还是文件,还是其他什么储存设备。一个领域对象是存储在一张表还是分开几张表,甚至是分开几个数据库,都是由基础架构层中的持久化模块来决定的,对领域层屏蔽实现的细节。只是在领域层需要持久化,或者需要反持久化的时候提供领域层需要的对象即可。

4 聚合

在进行面向对象设计的时候,我们会将一些对象进行组合,组合成为新的对象。随着系统的复杂,很容易造成对象的关系也复杂起来,对象的关系真的变成了错综负责的网状。

DDD提出的聚合可以解决这个问题,用来减少对象之间的关联关系。有聚合就有聚合根的概念,要不然就没有终点,还是会变成网状。我理解的聚合根,就是一个聚合的终点。聚合也可以理解为一系列对象,他们的关系好像树形,需要一个根节点来表达这一系列的对象。

 

4.1 如何发现聚合

那么如何来发现一个聚合呢?通过下面的一个小例子,我们来说明一下。

比如我们的场景是一个电子商务网站,需要定义一个商品类,商品肯定会有参数,图片,配送地域这些附属信息。我们一般会定义下面的类结构

public class Product
   {
       public Guid Id { get; set; }
       public string Name { get; set; }
       public List<Parameter> Parameters { get; set; }
       public List<Delivery> Deliverys { get; set; }
       public List<Image> Images { get; set; }
   }

   public class Parameter
   {
   }
   public class Delivery
   { }
   public class Image
   { }

 

其实这时候Product,Parameter,Delivery,Image就是一个聚合,Product就是这个聚合的根。因为Parameter,Delivery,Image这些概念脱离了Product是没有意义的,他们都是一个商品的附属信息,单独的谈论一张图片和一个参数没有任何意义。应该是从一个Product出发,然后引出来这个Product的参数,配送,图片,这样才比较合理。所以他们几个概念是一个聚合。

结束

今天我们就理解到这里,明后天我们再继续!!!

Technorati 标签: ,