领域驱动设计案例【Tiny Library应用服务层】

Tiny Library使用应用服务层向用户界面层提供服务,具体实现是采用Microsoft WCF Services。在Tiny Library的解决方案中,是由TinyLibrary.Services项目为整个系统提供这一WCF服务的。按照传统的应用系统分层方法,TinyLibrary.Services项目位于领域模型层之上、用户界面层之下,它是UI与Domain的交互界面。TinyLibrary.Services的实现中,与DDD相关的内容主要是数据传输对象(DTO),至于如何编写与实现WCF服务,那是.NET技术上的问题,本文不会做太多的讨论。

 

数据传输对象(Data Transferring Object,DTO)

在TinyLibrary.Services中,有一种特殊类型的对象,我们称之为数据传输对象。根据Fowler在PoEAA一书中的描述,DTO用于进程间数据交换,由于DTO是一种对象,它能够包含很多数据信息,因此,DTO的采用可以有效减少进程间数据交换的来回次数,从而在一定程度上提高网络传输效率。

由于DTO需要跨越进程边界(在我们的案例中,需要跨越网络边界),因此,DTO是可以被序列化/反序列化的,它不能包含上下文相关的信息(比如,Windows句柄)。正因为如此,DTO中的数据类型都是很简单的,它们可以是原始数据类型(Primitive Data Types)或者是其它的DTO。

有些朋友在阅读Fowler的PoEAA一书时,对于DTO的理解还是有困难,我在此将我的理解写下来,供大家参考

  1. 领域模型对象不负责任何数据传输的功能,这是因为,如果将领域模型对象用于数据传输,则势必需要在另一个层面(或者另一个进程中)产生一个领域模型对象的副本,此时才有可能在服务器与客户机之间产生一种数据契约,而这种做法违背了层内高内聚,层间低耦合的原则
  2. DTO是简单而原始的,并且是运行时上下文无关的。这是为了满足序列化/反序列化的需求。因此,DTO所包含的数据要不就是原始数据类型,要不就是其它的DTO
  3. 客户端需求决定DTO的设计。因此,DTO与领域模型对象并非一一对应的关系,相反,它是为了满足客户端需求而存在的

在Tiny Library案例中,我选用了WCF的Data Contracts作为DTO的实现标准,因为这样做不仅能够基于客户端需求设计合理的DTO结构,而且还可以利用WCF的DataContractSerializer实现DTO的序列化/反序列化。不仅如此,WCF为我们在服务器与客户机通讯上提供了技术支持和有力保障。

打开TinyLibrary.Services项目,我们可以看到一个IDataObject的泛型接口,其定义如下:

隐藏行号 复制代码 IDataObject定义
  1. public interface IDataObject<TEntity> where TEntity : IEntity
    
  2. {
    
  3.     void FromEntity(TEntity entity);
    
  4.     TEntity ToEntity();
    
  5. }
    
  6.  

我们可以要求所有的DTO都实现这个接口,以便使其具有将实体转换为DTO,或者将DTO转换为实体的能力。在Tiny Library案例中,我并没有强制要求所有的DTO都实现这个接口(也就是说,Tiny Library本身不规定DTO必须实现这个接口),我引入这个接口的目的,就是想说明,其实我们是可以这样做的:在我们的系统中为DTO设计好一个合理的框架,以便让DTO获得更强大的功能。引入这个接口的另一个目的就是为了编程方便:实现基于某个实体的DTO,只需要使其实现IDataObject接口即可,Visual Studio会自动产生方法桩(Method Stubs),无需手动编写代码。

请注意TinyLibrary.Services.DataObjects.RegistrationData这个类,它与BookData、ReaderData有很大的区别,它并不是Registration实体的映射体现,换句话说,它所包含的所有状态属性,并不是与Registration实体所包含的属性一一对应。例如,RegistrationData这个DTO中包含书名(BookTitle)以及ISBN号(BookISBN)的信息,而这些信息都是来自于Registration的关联实体:Book。RegistrationData的设计完全是为了迎合用户界面,因为在UI上,我们需要针对某个读者列出他/她的借书信息,而RegistrationData包含了这所有需要的信息。

 

应用层职责

在《Entity Framework之领域驱动设计实践》系列文章中,我曾经提到过,根据DDD,应用系统分为四层:展现层、应用层、领域层和基础结构层。在Tiny Library案例中,TinyLibrary.Services充当了应用层的职责,它不负责处理任何业务逻辑,而是从更高的层面,为业务逻辑的正确执行提供适当的运行环境,同时起到任务协调的作用(比如事务处理和基础结构层服务调用)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值