2

我正在开发一个实现多层模式的应用程序,其中 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 是常见的还是我应该使用域对象(我知道这里已经讨论了很多,但据我了解,如果域对象不是那么复杂并且可以节省映射和编码,它将适用更改我的域对象和数据库时需要努力)这会不会导致非常难以维护的通信链,例如:实体<->域对象<->DTO<->域对象
  5. 你把验证放在哪里?我想将基本验证放入视图或演示者中(例如,格式化、null/not null 值,......),而主要验证进入域对象......?
  6. 在数据库中创建新记录时,假设是一个新用户,客户端是否也应该将新的 DTO 传递给服务器,还是创建一个接受简单数据类型(如字符串和 int)的服务方法更好?

很抱歉这篇长篇文章,但我认为最好将我的问题合并到一篇文章中并在其中提供项目结构。

提前感谢您的任何回答。

问候

4

2 回答 2

4

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

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

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

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

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

最后,如果你真的需要 DDD,而且你是新手,你会发现Epic 的建模模式很有用(免责声明,我是 Epic 开发人员之一,我在过去 5 年的 DDD 试验和错误中设计了所有这些模式)。

于 2013-04-02T15:42:00.593 回答
0

我会一一解答

1)它取决于应用程序的复杂性。如果您正在处理复杂的领域,那么遵循领域驱动设计是很好的

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

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

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

5) 根据范围在每个组件中进行验证是很好的

6) DTO 会更好

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

于 2013-04-02T14:20:46.110 回答