C# 从活动记录移动到域对象模式方法
以下是场景: 我已经加入了一个团队,他们正在开始开发一个相当大的金融系统,并且应该以DDD为目标,拥有丰富的行为领域模型。然而,在项目的当前区域中,我可以看到许多指向活动记录的气味:应用程序服务中的单个“保存”方法;一组相当贫乏的域对象,它们有一个大的“验证”方法等。所有这些都非常粗糙,并且变得越来越难以管理 我正在开发的用户故事大致可以翻译为“当直接借记从特定状态转换到另一个状态(未编入预算到编入预算)时,创建一个任务项供顾问处理”。有各种规则确定“未编入预算”和“编入预算”的含义 目前,DirectDebit类根本没有“状态”的概念,它是一个相当大的DTO(有几个子对象——同样是所有DTO),有大约1000行验证逻辑,试图确定它应该是什么形状。业务部门对直接借记可能处于的不同状态有“清晰”的概念,我相信该领域足够丰富,可以保证一个领域模型 DirectDebit应用程序服务有一个“Save”方法,用于传入更新的DirectDebit(从UI)。该方法从存储库中获取现有的DirectDebit,完全忽略它,对更新的DirectDebit对象运行“Validate”,并将其保存到repo。然后,该方法审核新旧直接借记对象之间的更改 我试图摆脱这里开始发展的积垢般的怪物,并向团队演示如何开始重构它 理想情况下,我希望开始重构域对象以使用状态模式,使用良好的封装,或者使用域事件来冒泡状态已更改的事实。应用层将有一个名为“CreateTaskWhenBudget”或类似的域事件处理程序来解耦逻辑 我的问题是大型“保存”直接借记方法,它起源于UI 有什么策略可以分解/重构这种方法吗?没有简单的方法来判断“改变”了什么,因为没有一个明确的命令正在发生。或者,我是否应该继续增加混乱,忽略我认为是问题的东西 下面是应用程序服务的精简版本:C# 从活动记录移动到域对象模式方法,c#,activerecord,domain-driven-design,C#,Activerecord,Domain Driven Design,以下是场景: 我已经加入了一个团队,他们正在开始开发一个相当大的金融系统,并且应该以DDD为目标,拥有丰富的行为领域模型。然而,在项目的当前区域中,我可以看到许多指向活动记录的气味:应用程序服务中的单个“保存”方法;一组相当贫乏的域对象,它们有一个大的“验证”方法等。所有这些都非常粗糙,并且变得越来越难以管理 我正在开发的用户故事大致可以翻译为“当直接借记从特定状态转换到另一个状态(未编入预算到编入预算)时,创建一个任务项供顾问处理”。有各种规则确定“未编入预算”和“编入预算”的含义 目前,Di
public void SaveDirectDebit(DirectDebit directDebit)
{
directDebit.Validate(false);
var beforeDirectDebit = _directDebitRepository.FetchDirectDebit(directDebit.ExpenditureId.Id);
_directDebitRepository.SaveDirectDebit(directDebit);
var afterDirectDebit = _directDebitRepository.FetchDirectDebit(directDebit.ExpenditureId.Id);
var accountAuditLog = CreateDirectDebitAudit(beforeDirectDebit, afterDirectDebit);
_auditLogRepository.CreateAudit(accountAuditLog);
}
当然,没有一种方法可以做到这一点(好方法与其他方法相比),您有多个参数(时间、复杂性…) 由内而外的方式 免责声明:遗留代码越庞大,这种方法就越难以实现(对我来说,成功的条件是:你不应该是唯一关心这种重构的人) ->保存到数据库是一项技术工作。您必须首先引入一些普遍存在的语言,以使隐式显式,并能够引入概念和进行设计(创建边界和单独的上下文) 另一种方式
另一方面,它是我在评论中开始描述的,对我来说,它与Eric Evans所说的“泡沫上下文”有关。当你被一个遗留系统包围时,从一个干净的小有界上下文开始更容易。这种隔离将帮助您应用比现有系统更好(不同)的设计。当您正在开发一个新的用户故事并且您知道触发因素时,为什么不公开不同的方法?在第一次你可能会重复代码…这是一个公平的点-我可以公开第二个方法,但我可能会保存到数据库两次。我希望有一种从内到外的重构方法。