多层体系结构 - 责任问题

时间:2013-04-02 13:29:57

标签: architecture domain-driven-design dto n-tier-architecture multi-tier

我正在开发一个实现多层模式的应用程序 MySQL用于持久化。有一个提供访问的WCF服务 数据和提供DTO。

此外,我计划实施以下模式: - DTO - MVP(尚未确定被动视图或监督控制器) - 适用的接口代码

目前,我原本拥有以下项目结构:

+-------------------------------+
|     MySQL DB Server           |
+------+------------------------+
       ^
       | Uses Entity Framework 5.0
       |
       +
+-------------------------------------------------------------------------------+
| Application Server                                                            |
|-------------------------------------------------------------------------------|
|+------------------+ +----------------+ +--------------+ +--------------------+|
|| Data Access Layer| | Contracts      | | Communication| | Business Layer     ||
||------------------| |----------------| |--------------| |--------------------||
|| - EF 5.0 Entities| | - WCF Contracts| | - WCF Service| | - Actual Service   ||
||                  | |                | |   Hosts      | | - Session management|
||                  | |                | |              | | - Security and     ||
|+------------------+ +----------------+ +--------------+ +--------------------+|
+-------------------------------------------------------------------------------+
        ^
        | Communicates via DTOs which are acutally wrappers for Entities
        | eg. GetUserByID() or SaveUser(userDTO)
        |
        |
+-------+-----------------------------------------------------------------------+
| Clients                                                                       |
|-------------------------------------------------------------------------------|
|+-------------------+                                     +-------------------+|
|| Business Layer    |+----------------------------------->| GUI (Winforms)    ||
||-------------------|  BLL receives DTOs and creates      |-------------------||
|| -Provide WCF Servi|  Domain Objects (eg. User) which are| -Implementation of||
||  ce Access        |  Processed by presenters and passed |  View Interfaces  ||
|| -Service Reference|  to views where they are bound to   |                   ||
|| -Implementation of|  controls.                          |                   ||
||  Presenter Interf.|                                     |                   ||
|+-------------------+                                     +-------------------+|
+-------------------------------------------------------------------------------+



+------------------------------------------------------------------------+
| General                                                                |
|------------------------------------------------------------------------|
|+---------------------+ +--------------------+ +-----------------------+|
|| DTOs                | | Interfaces         | | Library               ||
||---------------------| |--------------------| |-----------------------||
|| -DTO Definitions    | | -View Interfaces   | | -General Helper Classe||
||                     | | -Presenter Interf. | |  s eg. Cryptography   ||
||                     | | -Domain Model IF.  | |                       ||
|+---------------------+ +--------------------+ +-----------------------+|
+------------------------------------------------------------------------+

外部框是Visual Studio中的项目文件夹。内盒是 C#项目

在我继续编码并在实际实施中花费更多时间之前,我只是 想得到关于我的项目的结构/架构的一些反馈。

我正在围绕以下问题解决:

  1. 上述结构是“最佳实践” - 符合规定吗? 例如。接口的位置,DTO
  2. 是否可以使用两个业务层,或者分割业务层 进入客户端和服务器? 服务器BLL旨在提供会话管理等常规功能 客户端BLL提供服务访问时的安全性。它控制着 主持人的观点也是如此。
  3. 服务器端目前不知道域对象。会吗 在这里使用它们会更好吗?这将导致我的映射 实体到域对象然后到DTO
  4. 从WCF服务接收DTO是否常见,或者我应该使用域 对象(我知道这里已经讨论了很多,但是从那里开始 我理解,如果域对象不是,那将是适用的 这很复杂,可以在更改时保存映射和编码efford 我的域对象和数据库) 这不会导致非常难以维护的通信链: 实体< - >域对象< - > DTO< - >域对象
  5. 你在哪里进行验证?我想把基本的验证放进去 视图或演示者(例如格式化,null / not null值,...)while 主要验证转到域对象......?
  6. 在数据库中创建新记录时,假设是新用户, 客户端是否也应该将新的DTO传递给服务器,或者更好地创建 一种接受简单数据类型的服务方法,例如string和int?
  7. 对于这篇长篇文章感到抱歉,但我认为将我的结合起来会更好 将问题分成一个帖子并提供项目结构。

    提前感谢任何答案。

    此致

2 个答案:

答案 0 :(得分:3)

您建议的结构与我们2年前在生产中部署的应用程序非常相似( mutatis mutandis )。它有效,但您必须仔细设计域模型,在不同的有界上下文中分离应用程序的各个方面。

所以这些是我自己的答案:

  1. 不,这里没有“最佳实践”。经过5年的金融应用DDD实践,我个人认为DDD仍然是一个研究领域。但是,如果项目的价值在于域专家的体验,则可以很好地应用它。但是,您必须区分业务需求(与域相关)和技术需求(可以帮助绘制应用程序所需的组件和层)。
  2. 业务层(如果您需要识别一个)应该只处理业务规则。它是DDD应用程序中域模型的一层。
  3. 根据我的经验,如果您可以信任客户端计算机并且正确设计了域模型,则根本不需要任何Application Server。但是,如果你真的需要它(例如因为客户端无法连接到数据库),我会尽可能简单和无状态。这里一个有用的考虑因素是大多数时候,业务规则已经阻止了对可变实体的并发访问。在这种情况下,不要尝试处理对这些实体的并发访问,只需构建一个互斥机制。
  4. 对于进程间通信,仅使用DTO。但是,您可以选择将整个域移动到Application Server中(这将变得更加复杂和有状态),并在客户端中使用更简单的MVC模式。从客户端的开发人员的角度来看,这更简单,但总体上更昂贵(特别是,它可能难以扩展)。
  5. 输入字段的简单类型验证可以在视图中完成(整数,日期时间等),但您应该使用自定义值对象为每个相关类型的值建模,然后再将其传递给域名。例如,您不应该将字符串或小数传递给域对象,而是电子邮件资金。此外,该域只负责业务不变量:it should throw expressive exceptions当无法执行操作时。
  6. DTO更具表现力,因此更容易调试。
  7. 在你开始之前,我想你应该问自己一些问题:

    1. 我是否需要领域专家,或者我可以通过阅读维基百科或一套精心编写的规范来学习足够的业务?提示:不需要(至少)领域专家==不需要DDD。
    2. 我可以信任部署客户端的计算机吗?如果不能,则应考虑将域移动到Application Server(并采用MVC模式客户端来处理WCF请求和DTO绑定)。
    3. 最后,如果你真的需要DDD,并且你是新手,你会发现Epic's modeling patterns很有用(免责声明,我是Epic开发者之一,我在过去的5年中设计了所有这些DDD试验和错误)。

答案 1 :(得分:0)

我将逐一回答

1)它取决于应用程序的复杂性。如果您正在开发复杂的域,那么可以遵循域驱动设计

2)如果你说BLL,它应该只关注业务逻辑而不是任何技术细节,如会话,安全性。

3)在服务器端拥有域对象很好。它促进了可重用性

4)您不应该在外面公开域对象。 DTO是更好的选择。您可以将Automapper用于所有与映射相关的工作

5)根据范围

,在每个组件中进行验证是件好事

6)DTO会更好

此外,您可以使用服务堆栈而不是WCF,因为它基于行业最佳实践。