这里是 –
假设我想建立一个应用程序来保存数据库中的“人”相关数据在wpf datagrid中显示个人详细信息(DDD绝对不适用于这种规模的应用程序,但只是为了保持简单的像我这样的功能)。所以,我设计了一个域类“人”,像 –
public class Person { public Class1(dataType fieldAParam) { _fieldA = fieldAParam; } private dataType _fieldA; public dataType PropertyA { //encapsulates _fieldA } private dataType _fieldB; public dataType PropertyB { //encapsulates _fieldB } private dataType _fieldC; public dataType PropertyC { //encapsulates _fieldC } public dataType PropertyX { //some code based on private fields } public dataType PropertyY { //some code based on private fields } private dataType MethodPQR(dataType param) { //some code } public dataType MethodUVW(dataType paramOne,dataType paramTwo) { //some code } }
现在,我对DDD的理解说,架构(最简单的版本)应该如下(如果我错了,请纠正我) –
注意:
>我希望datagrid绑定到一些ObservableCollection,只是为了立即反映任何种类的变化。
>这是一个wpf应用程序,但不一定是在MVVM模式&我故意使用后面的代码(我不知道自己的代码是否代表应用层)
所以我的问题是 –
>应用层应该属于什么样的代码?
>我的猜测是,我绝对不要将我的域对象(Person)的ObservableColletion绑定为datagrid的itmsSource。我应该从域对象中提取什么类型的对象,&怎么样?
>为了在表示层对象和域图层对象之间保持解耦可能有一个约定,例如“从不在表示层中直接实例化域对象”。那么那么“非”直接的方法呢?
>如果Code-Behind与应用层交谈,那么应用层应该与存储库进行交流?但是如果需要某种类型的域访问,那就是数据访问相关(可能不在这个应用程序中,但可能会发生,对)?应用层应该与域层中的X人在一起吗?
我知道我所有的问题和问题都非常成熟。但他们确实是问题和问题。所以,如果有人有时间,任何回应将不胜感激。
编辑:我不知道数据存储库应该有域模型的引用。
如果您不允许域名以外的域对象本身,则通常将使用DTO或数据传输对象,这些对象是仅具有属性的简单属性,不具有域行为。 DTO经常反映领域模型结构,但不一定要。
业务逻辑应该在域模型中实现,应用层中的大部分内容涉及协调各种服务,通常是将数据传入和传出客户端应用程序。许多人为此使用某种形式的SOA或至少Web服务。这些调用存储库,但也需要其他组件(如汇编器)来获取从存储库调用返回的域对象,并将属性值复制到DTO中,然后将其序列化并返回给调用者。调用者通常是演示者或控制器,但是如果您不使用MVC或MVP,则呼叫者仍将在演示层中。反向行程更复杂 – UI可以发回表示要添加的新对象的更新或DTO的DTO。调停这些来回活动主要是应用层的目的。
就域层的“非数据访问”而言,有几个典型的例子。大多数人通常会将您可能认为是域服务的“X”组件。域服务与应用服务的区别在于与域模型的接近以及实际业务逻辑的存在。
例如,如果申请涉及某种类型的订单,实际上有两个问题 – 订单放置和订单履行。应用程序服务中介将订单放置所需的数据传输到UI,然后返回用户希望放置的订单。但这只是中介数据传输,这就是Application Services结束的地方。然后可能需要使用域服务来应用业务规则并构建实际完成该订单所需的其他域对象。
一般来说,我发现,作为一个有用的概念或隐喻,可以应用于许多场景 – 应用程序服务仅在请求提交方面促进某种请求。另一方面,域服务便于实际请求的实现。
除了面向数据的“访问”之外,我遇到或可以想象的唯一其他模式是面向过程的功能。这在每个应用程序中都没有遇到,但在某些领域很普遍。例如在我工作的医疗保健中,您可能希望包含管理临床数据和临床过程的重要元素的应用程序。我解决这个问题,不要把这个过程强调为我的域模型的一部分,而是使用不同的工具。
OOP技术不适合实际过程本身,它们可用于向流程提供数据和从数据流中获取数据。面向对象主要是以面向名词为主。对于实时过程管理,您需要“动态定向编程”,而不是“面向名词的程序设计”。工作流工具是“动态导向”工具,可以为数据密集型和流程密集型应用程序的域驱动模型提供补充。我做了很多涉及C#DDD模型和Workflow Foundation模型的工作,但这仅仅是某些类型的应用程序需要的。许多典型的商业应用只需要域模型和服务。
最后,DDD的最重要的方面不是任何技术或架构。真正的心脏围绕无处不在的语言和互动(在我强烈的意见DIRECT互动)领域专家,以提炼出关键领域的知识。 (在我看来,大多数声称在做DDD的公司并不是因为这么多公司拒绝让业务和开发直接进行互动,而是另一个主题…)提取和并入域知识,而不是任何技术实际上将DDD与传统OOP分离,这就是DDD的实际价值。
编辑
就仓库使用而言,图表是正确的。通常,应用层始终通过域对象的存储库。首先,您必须能够将数据带到应用程序,而大多数应用程序也需要一定程度的查询能力。
域层OTOH通常不与存储库进行交互。通常,您希望域模型是自包含的,并与任何特定技术分离,即应该代表“纯域知识”。持久性本质上与某种特定技术紧密耦合,所以一般来说,人们努力使其领域模型不受任何持久性实现的影响。您有存储库,但您通常不想在域模型中调用存储库方法。
在域模型本身中,对象可以作为新对象(可以直接或通过工厂实例化)获得,也可以通过遍历关联来获取。有时,当创建一个新对象时,将所需的所有内容传递给构造函数是不切实际的,所以在这种情况下,您可能需要在域模型本身内进行某种数据访问。通常人们做的是通过接口传递数据服务,使得域模型可以被提供数据访问,但仍然与数据层实现分离。但是,对于大多数情况,域对象与已实例化的其他域对象进行交互。