DDD 示例:CargoRepository.Store() 可以在控制器中使用吗?
我正在查看来自 http://code.google.com/p/ndddsample 了解 DDD。我对某些事情感到困惑
CargoRepository 有一个由 BookingService.AssignCargoToRoute() 和 CargoTrackingController.Search() 调用的 Find() 方法:
Cargo cargo = CargoRepository.Find(trackingId);
CargoRepository 还有一个从 BookingService.AssignCargoToRoute() 调用的 Store() 方法:
Cargo cargo = cargoRepository.Find(trackingId);
if (cargo == null)
{
throw new ArgumentException("Can't assign itinerary to non-existing cargo " + trackingId);
}
cargo.AssignToRoute(itinerary);
cargoRepository.Store(cargo);
我的困惑是,似乎有没有什么可以阻止 CargoTrackingController 调用 CargoRepository.Store() ,这会绕过 BookingService.AssignCargoToRoute() 中的业务逻辑,
为什么 DDD 中允许这样做?存储库是否应该分为两部分,一份用于应用程序/ui/域/服务的读取,一份用于域/服务的写入?
I'm looking at the great NDDDSample source from http://code.google.com/p/ndddsample to learn about DDD. Am confused with something
The CargoRepository has a Find() method which is called by BookingService.AssignCargoToRoute() and CargoTrackingController.Search() :
Cargo cargo = CargoRepository.Find(trackingId);
CargoRepository also has a Store() method called from BookingService.AssignCargoToRoute() :
Cargo cargo = cargoRepository.Find(trackingId);
if (cargo == null)
{
throw new ArgumentException("Can't assign itinerary to non-existing cargo " + trackingId);
}
cargo.AssignToRoute(itinerary);
cargoRepository.Store(cargo);
My confusion is that there seems to be nothing to stop the CargoTrackingController from calling CargoRepository.Store() which would bypass the business logic in the BookingService.AssignCargoToRoute()
Why is this allowed in DDD? Should the repository be split into two, one for read for the application/ui/domain/service and one for write for the domain/services?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 DDD 中,服务并不是所有业务逻辑的持有者。它们仅代表与多个对象交叉关注的领域的动词、动作,因此不适合实体之一或聚合根,而不打破单一责任原则并创建会使实体混乱的紧密耦合。
在您的示例中, Cargo.AssignToRoute(itinerary) 和 BookingService.AssignCargoToRoute() 似乎是多余的。这两种将货物绑定到路线的方法的存在会造成混乱。您可以保留其中任何一个,具体取决于您是否认为 Cargo 有责任为自己分配一条路线,或者它使用不属于其中的功能使实体过载。
除此之外,控制器直接调用存储库方法是完全合法的。服务不是控制器的单一访问点。
In DDD, Services are not the holders of all business logic. They only represent verbs, actions of the domain that are cross-concern to several objects and thus wouldn't fit into one of the entities or aggregate roots without breaking single responsibility principle and creating tight couplings that would muddle the entity.
In your example, Cargo.AssignToRoute(itinerary) and BookingService.AssignCargoToRoute() seem to be redundant. The existence of these 2 ways to bind a cargo to a route creates confusion. You could keep either of them, depending on whether you think it is the responsibility of the Cargo to assign itself a route, or that it overloads the entity with functionality that doesn't belong in it.
Other than that, it is perfectly legitimate for a Controller to call a Repository method directly. Services are not the single point of access for Controllers.
嗯,我想这就是 CQRS 想要实现的目标。
当然,在这种情况下,绕过 BL 是一个坏主意(而且显然很容易实现,这更糟糕)。但是您无法在代码中强制执行所有规则,有些规则只会保留代码中未明确声明的约定。有些坏事可能很难,但仍然不是不可能实现,而且总是会犯很多愚蠢的错误。这就是编程的本质:你必须思考你真正在做什么,否则没有像 DDD 这样的指导方针可以帮助你完成它。
Well, I guess that's what CQRS is trying to achieve.
Of course in this case bypassing BL is a bad idea (and apparently quite easy to achieve, which is even worse). But you just cant't enforce all the rules in code, some will just stay conventions not explicitly declared in the code. Some bad things may be hard, but still not impossible to achieve, and there are always lots of silly mistakes one can make. That's just what programming is: you have to think what you're really doing, or else no guidelines, like DDD, will help you pull it off.
需要将应用程序分离到持久巢穴和服务巢穴中,以帮助您作为开发人员维护一些易于理解和维护的结构,开发人员有责任遵循某些模式并正确使用代码。
限制您(开发人员)错误使用它的不是框架,DDD 是设计模式(指导如何组织应用程序结构)。
The separation of application in persistence lair and service lair is needed to help you as a developer to maintain some structure that is easy to understand and maintain, it's developers responsibility to follow some pattern and use code properly.
It's not framework which restricts you (developer) from using it's incorrectly, DDD is design pattern (a guidance how to organize you application structure).