我们在委托与封装业务逻辑之间划清界限的地方是什么?在我看来,我们委派的越多,我们变得越贫乏。但是,委派还促进重用和DRY主体。那么什么是合适的委托,我们的领域模型应该保留什么呢?
以以下问题为例:
授权。域对象应该负责维护其访问控制规则(例如CanEdit属性)还是应该委派给另一个单独负责管理访问的组件/服务,例如IAuthorizationService.CanEdit(object)?还是应该将两者结合?也许域对象具有CanEdit属性,该属性委派给内部IAuthorizationService来执行实际工作?
验证。与上述相同的讨论涉及验证。谁维护规则,谁负责评估规则?一方面,对象的状态应该属于该对象,而有效性是一个状态,但是我们不想重写用于评估每个域对象的规则的代码。在这种情况下,我们可以使用继承...
对象创建。工厂类与工厂方法与“更新”实例。如果我们使用单独的工厂类,则可以隔离和封装创建逻辑,但要以将对象的状态打开给工厂为代价。如果我们的域层在单独的程序集中,则可以通过公开工厂使用的内部构造函数来进行管理,但是如果存在多个创建模式,这将成为一个问题。而且,如果工厂所做的所有工作都在调用正确的构造函数,那么拥有工厂的意义何在?
类上的工厂方法消除了打开对象内部状态的问题,但是由于它们是静态的,因此我们无法像通过单独的工厂类那样通过注入工厂接口来打破依赖关系。
坚持不懈。有人可能会争辩说,如果我们的域对象要在向另一方委派执行授权检查的职责时将CanEdit公开给他人(IAuthorizationService),为什么在我们的域对象上没有执行相同操作的Save方法呢?这将使我们能够评估对象的内部状态,以确定是否可以在不破坏封装的情况下执行操作。当然,这要求我们将存储库实例注入到我们的域对象中,这对我来说有点气味,那么我们是否应该引发域事件并允许处理程序执行持久化操作?
看看我要去哪里?
Rockford Lhotka对他为什么选择CSLA框架中的班级主管路线进行了精彩的讨论,而我对该框架有一些了解,可以看到他的业务对象以多种方式与域对象并行的想法。但是,我试图成为更好的DDD理想的坚持者,我想知道何时协作变得过多。
如果最终以聚合根为IAuthorizationService,IValidator,IFactory和IRepository,还剩下什么?是否具有将对象状态从“草稿”更改为“已发布”的Publish方法足以将类视为非贫血领域对象?
你的意见?