architecture - 多层架构 - 责任问题

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

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

此外,我计划实现以下模式: - DTO - MVP(尚不确定是被动 View 还是监督 Controller ) - 针对适用的接口(interface)进行编码

目前,我的项目结构如下:

+-------------------------------+
|     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. 上述结构是否符合“最佳实践”? 例如。接口(interface)、DTO 的位置​​
  2. 可以有两个业务层还是可以拆分业务层 分为客户端和服务器? 服务器 BLL 旨在提供 session 管理等通用功能 和安全性,而客户端 BLL 提供服务访问。它控制着 以及主持人的观点。
  3. 服务器端目前不知道域对象。会吗 在这里也最好使用它们吗?这将导致映射我的 实体到域对象,然后到 DTO
  4. 从 WCF 服务接收 DTO 是否很常见,或者我应该使用域 对象(我知道这里已经讨论了很多,但是从什么 我理解,如果域对象不是,那么它将适用 这很复杂,并且可以在更改时节省映射和编码工作量 我的域对象和数据库) 这是否会导致通信链非常难以维护,例如: 实体<->域对象<->DTO<->域对象
  5. 你把验证放在哪里?我想将基本验证放入 View 或演示者(例如格式化、空/非空值...) 主要验证针对域对象...?
  6. 在数据库中创建新记录时,假设有一个新用户, 客户端是否也应该将新的 DTO 传递给服务器,还是最好创建 接受简单数据类型(例如字符串和整数)的服务方法?

很抱歉这篇长文,但我认为结合我的观点会更好 问题集中到一篇文章中并提供其中的项目结构。

预先感谢您的任何答复。

问候

最佳答案

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

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

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

在开始之前,我认为你应该问自己一些问题:

  1. 我是否需要领域专家,或者我可以通过阅读维基百科或一组编写良好的规范来了解足够的业务知识?提示:(至少)不需要领域专家 == 不需要 DDD。
  2. 我可以信任将部署客户端的计算机吗?如果不能,您应该考虑将域移至应用程序服务器(并采用 MVC 模式客户端来处理 WCF 请求和 DTO 绑定(bind))。

最后,如果您确实需要 DDD,并且您是新手,您可以找到 Epic's modeling patterns有用(免责声明,我是 Epic 开发人员之一,所有这些都是我在过去 5 年的 DDD 试验和错误中设计的)。

关于architecture - 多层架构 - 责任问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15765429/

相关文章:

tdd - 聚合根是否应该在域驱动设计中实现接口(interface)

c# - 洋葱架构 : Core vs Domain

.net - DTO 和 IQueryable : assembling and disassembling DTOs

asp.net-mvc - MVC Ninject 我不想引用数据层而只想引用服务层

java - 有没有办法(例如 Eclipse 插件)从实体(JPA)自动生成 DTO?

c# - 我如何确定或判断一组类是否为 "spaghetti code"?

JavaScript - 如何在不使用 alert() 或 window.open() 的情况下创建对话窗口?

asp.net - 在 Web 表单中使用 Entity Framework 的正确抽象是什么

java - POJO 或 DTO 方法

events - 这个进程管理器状态应该被持久化吗?