Domain driven design 如何在主细节中处理实体创建/编辑

Domain driven design 如何在主细节中处理实体创建/编辑,domain-driven-design,desktop,entity,desktop-application,master-detail,Domain Driven Design,Desktop,Entity,Desktop Application,Master Detail,我想知道人们使用什么策略来处理主细节设置中实体的创建和编辑。(我们的应用程序是一个支持互联网的桌面应用程序。) 我们现在是这样处理的:在弹出窗口中为需要编辑的实体创建一个表单,并提供对象的副本。当用户单击“取消”按钮时,我们关闭窗口并完全忽略对象。当用户单击“确定”按钮时,主视图将收到通知并接收编辑的实体。然后,它使用originalEntity.copyFrom(modifiedEntity)将修改实体的属性复制到原始实体中。如果我们想创建一个新实体,我们会将一个空实体传递给弹出窗口,用户可以

我想知道人们使用什么策略来处理主细节设置中实体的创建和编辑。(我们的应用程序是一个支持互联网的桌面应用程序。)

我们现在是这样处理的:在弹出窗口中为需要编辑的实体创建一个表单,并提供对象的副本。当用户单击“取消”按钮时,我们关闭窗口并完全忽略对象。当用户单击“确定”按钮时,主视图将收到通知并接收编辑的实体。然后,它使用originalEntity.copyFrom(modifiedEntity)将修改实体的属性复制到原始实体中。如果我们想创建一个新实体,我们会将一个空实体传递给弹出窗口,用户可以像编辑现有实体一样编辑该弹出窗口。主视图需要决定是将接收到的实体“插入”还是“更新”到它所管理的集合中

我对上述工作流程有一些问题和看法:

  • 谁应该处理实体副本的创建?(主要或详细)
  • 我们使用copyFrom()来防止必须替换集合中可能导致引用中断的实体。有更好的方法吗?(实现copyFrom()可能很棘手)
  • 新实体收到的id为-1(服务器层/hibernate使用它来区分插入或更新)。这可能会导致在保存实体之前按id查找(缓存)实体时出现问题。我们是否应该为每个新实体使用临时唯一id
任何人都可以分享提示、技巧或经验吗?谢谢


编辑:我知道这个问题没有绝对错误或正确的答案,所以我只是想让人们分享他们处理主/细节情况的想法和优点/缺点。

有很多方法可以改变这种方法。请记住,任何解决方案本身都不可能是“错误的”。这完全取决于你处境的细节。这里有一种剥猫皮的方法

谁应该处理实体副本的创建?(主要或详细)

我将master视为持久化实体子集的内存中列表表示。我会允许主人处理对其列表的任何更改。列表本身可以是自定义集合。使用ItemChanged事件向主机发出通知,告知某个项已更新,需要持久化。激发NewItem事件以通知主机插入

我们使用copyFrom()来防止必须替换集合中可能导致引用中断的实体。有更好的方法吗?(实现copyFrom()可能很棘手)

我将不使用copyFrom(),而是将现有引用传递到详细信息弹出窗口。如果使用可枚举集合存储主列表,则可以将从list[index]返回的对象传递到details窗口。引用本身将被更改,因此不需要使用列表中的任何替换方法。按下OK时,触发ItemChanged事件。您甚至可以传递索引,以便它知道要更新哪个对象

新实体收到的id为-1(服务器层/hibernate使用它来区分插入或更新)。这可能会导致在保存实体之前按id查找(缓存)实体时出现问题。我们是否应该为每个新实体使用临时唯一id

更改是否不会立即持久化?使用确定插入的内容和更新的内容。还有更多的工作单元的例子。如果Java端没有太多内容,您可能需要查看.NET社区的一些博客文章。不管怎样,这个概念都是同一种动物


希望这有帮助

CSLA库对这种情况有很大帮助

但是,如果要自行实现:

如果有主对象,则主对象包含子对象列表

详细信息表单可以直接编辑子对象。由于所有对象都是引用类型,因此主对象将自动更新

问题是知道主对象是脏的,因此应该持久化到您的数据库或诸如此类的东西

CSLA使用IsDirty()属性处理此问题。在主对象中,您将查询每个子对象,查看它是否脏,如果脏,则保存所有内容(以及跟踪主对象本身是否脏)

您还可以处理INotifyPropertyChanged接口

至于你的其他一些问题:

你想分开你的逻辑。实体可以处理自身属性的存储和自身的完整性规则,但不同对象如何相互交互的逻辑应该是独立的。研究MVC或MVP等模式

在这种情况下,新子对象的创建应该在主对象中,或者应该在创建子对象然后将其添加到父对象的单独业务逻辑对象中

对于ID,使用GUID作为ID可以为您节省很多问题,因为这样您就不必通过与数据库对话来确定正确的ID。您可以在对象上保留一个标志,以确定它是否是新的(因此应该插入或更新)

同样,CSLA为您处理所有这些,但确实有相当多的开销


关于取消时的撤消:CSLA实现了n级撤消,但是如果您试图手动执行,我会使用CopyFrom函数,或者在取消时从持久层刷新对象的数据(重新获取)

我刚刚实现了这样一个模型,但没有使用NH,而是使用自己的代码在Oracle Db中持久化对象

我在相同的web表单中使用了主细节概念

就像我有主实体网格和在细节操作命令上一样,我在单击的主记录行下方打开一个窗口

在细节添加模式下,我只需填充