服务层验证与域对象验证;潜在的“滥用”域对象?
我看过很多书籍和文章示例都说将验证代码放入服务层中。保持域对象“哑”(又名纯 POCO)并处理域对象可能在服务层中执行的所有验证。
服务层似乎负责很多事情(或者至少可以如此);用户身份验证、角色身份验证、IoC 的脚本依赖对象(记录器、错误处理程序等)、脚本域对象、脚本存储库以及将域对象传入和传出存储库...哇!
在服务层中创建所有这些规则不会对您的域对象构成重大威胁吗?例如,如果某些程序员决定直接针对您的域对象编写消费代码并完全绕过服务层,会发生什么情况?那会很糟糕,但却是一个可信的情况。
如果您打算将很多职责放在服务层中,包括所有域对象验证,那么有没有办法在有人尝试直接编写脚本时“保护”您的域对象?例如,也许您的域对象现在没有被某个客户端(在本例中是服务层?)使用。
好的设计让我认为域对象应该不知道谁在调用它们以及它们是如何被调用的。
如果没有办法“锁定”域对象,那么为什么有这么多文章、书籍等建议将域对象验证放在服务层中呢?我想通过采取防御性编程立场,您应该构建防弹的域对象,并依靠服务层的简单代码层在 UI 和 BAL/DAL 之间转发和接收请求。
有没有人有过一些现实项目经验,被绕过服务层的人“滥用”他们的域对象?
I've seen lots of book and article examples saying to put validation code in your Service Layer. Keep the Domain Objects "dumb" (aka, pure POCO's) and handle all validation that a Domain Object might do in the Service Layer.
The Service Layer is responsible for so much it seems (or at least it can be); user authentication, role authentication, scripting dependency objects for IoC's (loggers, error-handlers, etc...), scripting Domain Objects, scripting repositories and passing Domain Objects to and from the repository... whew!
Doesn't creating all these rules in the Service Layer pose a substantial threat to your Domain Objects? For instance, what happens is some programmer decides to write consuming code directly against your Domain Objects and just bypasses the Service Layer altogether? That would be bad, but a believable situation.
If you are going to put a lot of the responsibilities in the Service Layer, including all Domain Object validation, is there a way to "protect" your Domain Objects is someone tries to script them directly? For instance, maybe some way your Domain Objects now they're not being used by a certain client (in this case, the Service Layer?).
Good design makes me think the Domain Objects should know nothing about who's calling them and how they're being called.
If there is no way to "lock down" the Domain Objects, then why are so many articles, books, etc suggesting that putting Domain Object validation in the Service Layer the way to go? I would imagine by taking a defensive programming position, that you should build your Domain Objects to be bullet-proof, and rely on your Service Layer for a simple layer of code to forwarding and receiving requests between the UI and the BAL/DAL.
Has anyone had some real-life project experiences with "abuse" of their Domain Objects from people that have bypassed their Service Layer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您可能误解了 POCO 的目的。据我了解,POCO 并不是一个只有属性和属性的贫血域对象。相反,POCO 根本不依赖于框架或复杂的继承模型。对象是灵活的,只关心它在域中的角色。
I think you may misunderstand the purpose of a POCO. A POCO, as I understand it, is not an anemic domain object with only properties and attributes. Rather a POCO simply is not tied to a framework or complicated inheritance model. The object is flexible and only concerned about its role in the domain.
它们是两种不同的设计理念。丰富领域模型与贫乏领域模型。
简短的答案是肯定的,您可以阻止直接访问您的域对象。
您可以使用多种技术来做到这一点:
1) 您可以通过仅将唯一的公共方法设置为 getter 来使所有面向公众的域对象不可变(即您无法更改数据)。所有修改对象的方法都可以受到保护或包为私有,因此只有正确打包的服务才能访问它们(至少在 Java 中)
2) 您只能向外部开发人员公开单独的类 - 因此,如果您有一个 Person 域类,您可以拥有一个您传递的 PersonInfo 类,它除了包含信息之外什么也不做。
3) 您应该向您的应用程序使用者公开一致的 API。您基本上可以防止他们绕过您的服务层。
They are 2 different design philosophies. Rich Domain Model vs Anemic Domain Model.
The short answer is yes, you can prevent direct access to your domain objects.
You can do so with a number of techniques:
1) You can make all public facing domain objects immutable (i.e. you can't change the data) via only having the only public methods be getters. All methods that modify your objects can be protected or package private so only the correctly packaged services can access them (in Java at least)
2) You can expose only separate classes to your external developers -- so if you have a Person domain class you can have a PersonInfo class that you pass up, that does nothing but contain info.
3) You should expose a coherent API to your app consumers. You basically prevent them from bypassing your Service layer.