在 WPF 应用程序中使用 MVVM 和 DDD 而无需太多 类

Using MVVM and DDD in WPF application without having too many classes

我有一个 WPF 应用程序,我想在其中为表示层应用 MVVM,为整个应用程序应用 DDD。我对应该如何应用该体系结构感到非常困惑。你能给我一些建议吗,因为感觉我现在已经完全搞砸了以下设计尝试:

我有4层:

让我们用那些基于 DDD 的层实现一个简单的场景:在数据库中有一个 Person 对象,映射它,CRUD 数据库,检查人的生日并将其显示给用户。


表示层

我将从 WPF 部分开始。我创建以下 类 :


领域层

这对于表示层来说已经足够好了。我现在想连接到数据库以检索一个人对象来呈现它。

我必须创建:


应用层

好的,我已经有 3 个非常相似的人物模型了。数据访问和服务的更多内容如何?


总而言之,对于一个简单的场景,我最终得到了 7 类 :

  1. Presentation.WpfClient.View.PersonView
  2. Presentation.WpfClient.ViewModel.PersonViewModel
  3. Presentation.WpfClient.Model.PersonModel
  4. Application.ApplicationServices.PersonService
  5. Domain.Application.Services.PersonService
  6. Domain.Application.Models.Person
  7. Domain.Application.DbEntities.PersonEntity (我创建这个的原因是我不能对复杂的域对象使用映射,所以我只是在这里放一些数据注释而不是映射域对象)

这感觉非常非常别扭。我不确定我应该如何重新构建它并使域驱动设计和 MVVM 模式受益。我真的被困住了,我真的很期待任何关于应用 MVVM 和域驱动设计的建议或现实生活中的例子。我也欢迎任何关于命名约定或策略的反馈,以尽量减少简单操作的大量工作。

不过我还有两个具体问题:

  1. 我是否应该从表示层(MVVM 模型)中删除模型并仅使用领域层中的模型(DDD 模型)?这时候是不是违反了MVVM?

  2. 我应该将我的实体(数据库)模型与域模型合并吗?是不是违反了DDD?


更新

我做出的决定:

最后看起来像这样:

  1. Presentation.WpfClient.View.PersonView
  2. Presentation.WpfClient.ViewModel.PersonViewModel
  3. Application.ApplicationServices.PersonService(带有一些与应用程序相关的逻辑)
  4. Application.ApplicationServices.Mappings(我这里有存储库抽象和映射)
  5. Domain.Application.People.Person(person 对象在其有界上下文中,对象足够智能以处理领域逻辑)

关于你的第一个问题,使用领域层模型作为 MVVM 模型并不违反 MVVM (See definition of Model here)

有关该主题的更多详细信息和第二个问题的答案,请参阅:Entities VS Domain Models VS View Models

DDD 最有利于处理复杂的业务问题。在实际项目中,应该根据领域的复杂程度以更灵活的方式使用它。我想采用多种策略的方法来采用它。

  1. 对于大多数情况,主要是关于 CRUD 数据,数据结构几乎没有变化。我只会使用:

    表示层:ViewModel
    服务层:ViewModel<->Domin 对象
    领域层:与实体相同的领域对象

  2. 对于更复杂的域,域对象上有许多重要且可重用的业务逻辑,那么我会添加核心服务(如您的Domain.Application.Services.PersonService)。

  3. 如果处理数据还需要复杂的业务逻辑,以便更容易地在表示层和域层之间映射数据。我会在服务层中添加另一个模型,类似于您的 Presentation.WpfClient.Model.PersonModel。

所以基本上你现在拥有的架构已经准备好处理你的项目中的 Person 域非常复杂的情况。但是根据你的描述我目前还看不到。

回答您的问题:

  1. 您可以删除 MVVM 模型中的 Presentation.WpfClient.Model.PersonModel。它不违反 MVVM,因为在这种情况下,您的域对象是模型,并且您有 Presentation.WpfClient.ViewModel.PersonViewModel 作为 ViewModel。

  2. 如果您的个人域没有复杂的业务逻辑,您可以将实体与域对象合并。

对于一个概念来说,类 太多了。

Should I remove models from presentation layer (MVVM models) and use only models from domain layer (DDD models) ? Isn't it violation of MVVM at this point?

是的,在很多情况下这是一个更可取的解决方案,尤其是当您不使用像 WCF 这样的通信机制时。这里没有违规,因为 MVVM 没有强加模型部分的特定实现。

Should I merge my entity (database) models with domain models? Isn't it violation of DDD?

还有,是的。将一个实体分成两个(领域实体和 "persistence" 实体)通常会导致过度复杂化和贫血的领域模型。更多相关信息:Having the domain model separated from the persistence model.

总体而言,我建议您查看 this 示例。这看起来正是您所需要的:使用 MVVM 和 DDD 以 WPF 编写的成熟应用程序。