我正在设计API.我想知道我提出的是一个很好的解决方案:
我有一个存储库类型的数据层,通过将业务类转换为实体(从LLBL GEN生成,我不想直接使用实体作为我的业务对象,与数据库对话,因为我想保持它们简单并允许我交换到Entity Framework或其他一些mapper是我需要的)
我有一个WCF服务层,我正在使用它作为一种外观.它调用存储库层并将业务对象转换为DTO,并通过API服务调用将它们传递给客户端.客户端可以是ASPX网站,Silverlight应用程序,WPF应用程序,甚至是WP7应用程序.我保持运行的问题是当我想运行业务逻辑时,我必须将DTO发送回WCF服务然后再返回客户端.这对我来说似乎并不“正确”.我不能把业务逻辑放在DTO中,因为这会破坏目的.但是,如果我希望在客户端上运行业务类型代码,那么在我的不同客户端中我会有大量的代码重复.
我的业务层不知道数据层,我的数据层知道业务层,我的外观层知道数据层和业务层以及DTO.这对API来说是一个糟糕的设计吗?任何人都可以给我任何建议吗?我只是通过在线阅读不同的文章了解了企业级应用程序.
谢谢!
最佳答案:
层之间的关系
如果我理解您的设计,业务层不知道(=不使用)数据层,并且外观实际上通过将DAO转换为DTO来互连它们,反之亦然.
您应该考虑一种相当不同的方法:为所有与数据相关的对象(无论是DAO还是DTO)定义接口,并使用Inversion-of-Control容器将业务层和数据访问层编织在一起.原因是在您的设计中,您可能很快就会无法在业务层中检索其他数据.你最终会用这个缺点代替这个缺点,因此做了太多的实际业务逻辑.
如果您在业务层和底层数据层之间建立了明确的连接,同时使用精心设计的接口和IoC容器将它们分开,则可以在保持良好和简洁的内部设计的同时防止出现此问题.
DTO的用法
我认为你必须将DTO传递回应用程序的后端.在您的情况下,DTO的目的是(1)为表示层提供信息,以及(2)提供将修改的或新数据传递到后端以进行进一步处理的方法.案例(1)和(2)的DTO不必相同.因此,如果它有意义,您可以传递给后端只是一个代表整个信息子集的DTO.
但是,后端应在处理后返回一个新的DTO,同样不需要与输入DTO相同的DTO.这样,表示层可以很容易地适应后端对整个对象的相关部分所做的更改.
想象一个简单的Get / Update API,例如:
CustomerDTO GetCustomer(int customerID);
CustomerDTO UpdateCustomerAddress(int customerID, AddressDTO address);
CustomerDTO UpdateCustomerPrimaryContact(int customerID, PersonDTO primaryContact);
您正在使用ID来标识客户并传入代表要更新的客户记录子集的DTO(无论基础数据架构如何). out DTO代表整个客户,简化了表示层更新显示给用户的信息的任务.优点是后端不需要知道表示层实际需要哪个客户数据子集,并且表示层只能传递那些真正被修改的部分的后端.
更新 – 技术说明:考虑使用像AutoMapper(C#)这样的工具来自动执行DTO和DAO之间的转换.虽然这个问题是所使用技术的主题,但通常这种方法可以节省大量的手工工作,并且能够消除难以发现的错误.实现这样的对象翻译自动化有助于促进更好的设计实践,并允许您生成更专业化,因此语义更准确的DTO.
免责声明:虽然这是一个相当普遍的问题,但就您的申请的进一步细节而言,我的建议似乎并不正确.