我已经阅读了几篇强调声称保持域模型和持久性模型分离的文章.除非ID具有域用途,否则不要让ID之类的内容泄漏到您的域模型中.根据该政策,如何在实践中坚持域模型?我读过的所有文章都在摘要中讨论这个问题,但我找不到一个不违反这个问题的具体例子.
我有一个相对庞大而复杂的Web应用程序,我正在构建并希望实现“最佳”域和持久性分离.我正在使用手动ORM(是的,是的,我知道 – 我不应该 – 等等等等 – 但是,基础表和查询太复杂了,不能使用像EF或NHibernate这样的东西).在大学的这个会计软件包中,我有总帐日记帐分录,结构如下:
Public Class Journal Public Property AccountCode As SFSAccountCode = nothing Public Property Amount As Decimal = 0 Public Property Budgetcategory As Budgetcategory = nothing Public Property [Date] As DateTime = nothing Public Property ChildAccount As ChildAccount = nothing Public Property Description As String = "" Public Property FiscalYear As SFSFiscalYear = nothing Public Property Fund As Fund = nothing Public Property JournalID As Int32 = -1 Public Property Notes As String = "" Public Property Program As String = "" Public Property Source As JournalSource = nothing Public Property Status As JournalEntryStatus = JournalEntryStatus.Open Public Property TransactionType As TransactionType = nothingEnd Class
如果不包含uniqueID(JournalID),如何将域模型中的实例映射到持久性模型中的实例?根据我的理解,您将通过其不变量来考虑唯一的对象.如果您的对象只有一个或两个属性作为字符串或整数,则很容易.我显然有许多属性,其中有几个是域模型本身.
我确信有一些我错过的关键概念 – 任何人都可以指向一个资源(具体代码为奖励!)来帮助解释如何在没有数据库ID的持久模型与域模型之间进行映射?
顺便说一句,我知道我的属性应该是私有集合,用于良好的域设计.他们将有一次我可以更好地找出持久性和域之间的映射.我碰巧在VB.NET中编写代码但可以读取Java或C#,因为我确信大多数示例都是这两种语言中的一种.
解决方法 根据Domain Driven Design:关于实体和价值观的一些话
有权限对象(实体)和值对象(值).值由一组值(或字段)标识.因此,如果我们有两个具有相同字段的值对象,它们对我们来说并不是不可分割的(作为现实生活中的模型).值对象通常是不可变的.
实体对象不由包含的值标识.实体对象由其自身唯一的存在来标识.我们不能说两个同名的人提出单身真人.
例如:
class ProductAmountPair { public Product Product { get; set; } public int Amount { get; set; }}class Order { public int ID; public IList<ProductAmount> { get; set; }}
ProductAmount是一个值,Order是一个实体(实际上它取决于具体情况).
要识别实体对象,有必要确定一些唯一值(键).在某些域中,密钥是从外部给出的(来自现实生活),但是另外一些密钥需要生成密钥,因此应用程序本身定义了一种方法.
因此,结论是:对于实体,我们必须引入关键字段来识别它们.这是必要的,因为实体不能通过它们包含的一组值来识别.
数据库
好的,数据库及其角色怎么样?
今天,数据库不仅仅是数据存储,而且是用于确保数据完整性,事务处理等的复杂机制.通常,复杂的任务(如并发访问)仅通过将它们“广播”到数据库来解决.
出于同样的原因,数据库通常用于生成关键值,它们提出了获得新的唯一值的良好可靠机制.
因此,密钥是由数据库生成的,因为它易于实现,并且密钥用于将域模型实体映射到持久性模型,因为它很自然.
可以说,数据库引擎需要为每个表创建主键,因此域中的每个类都应该具有键字段,因此它是实体.但:
>关系数据库引擎使用主键进行引用,不应以任何方式影响域模型
>对于实值类型(如描述的ProductAmount类),不应使用存储在DB键中从数据库中获取相应的对象.它没有任何意义,因为某些键(通过值类型的定义)无法识别值对象.但是存储在数据库中的密钥用于加载对象关联.因此,此 *** 作必须由ORM封装.此外,从数据库获取值对象的唯一方法是从某个实体的字段中获取它.
坚持和领域
在谈论域时,我们为什么要考虑数据库(甚至关系数据库!)?在他的DDD书中,埃里克埃文斯说“不要面对技术和范式”.
有时,由于强大的性能或可靠性要求,我们必须放弃一些DDD纯度和清晰度,并使域模型更多(例如)“关系”(我的意思是大多数类表映射).
我们只需处理它.
出于同样的原因,我们可以承认实体关键领域的部分“技术”角色.但我们也承认其主要作用是域名识别属性.
总结以上是内存溢出为你收集整理的domain-driven-design – 持久性模型和域模型之间的映射全部内容,希望文章能够帮你解决domain-driven-design – 持久性模型和域模型之间的映射所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)