服务层验证与领域对象验证;领域对象的潜在“滥用”?

4
我看到很多书和文章的例子都说要把验证代码放在您的服务层中。保持域对象“愚蠢”(也就是纯POCO),并处理服务层可能执行的所有验证。
服务层似乎要负责很多事情(或者至少可以这样),例如用户身份验证,角色身份验证,为IoC编写脚本依赖项对象(日志记录器、错误处理程序等),编写域对象、存储库和传递域对象到和从存储库… 哇!
在服务层创建所有这些规则是否会对您的域对象构成重大威胁?例如,如果某个程序员决定直接针对您的域对象编写消费代码,完全绕过了服务层,那将是很糟糕的情况,但这是一个可信的情况。
如果要将许多职责放在服务层中,包括所有域对象验证,是否有一种方法可以“保护”您的域对象,以防止有人尝试直接对它们进行脚本处理?例如,也许有一些方式能够让您的域对象知道它们不是被某个特定客户端(在这种情况下是服务层)使用?
良好的设计使我想到域对象不应该知道谁在调用它们以及它们如何被调用。
如果没有办法“锁定”域对象,那么为什么有这么多文章、书籍等建议在服务层中放置域对象验证?我想通过采取一种防御性编程的立场,应该将您的域对象构建成防弹衣,并依靠您的服务层作为一个简单的代码层来转发和接收UI与BAL/DAL之间的请求。
有没有人在实际项目经验中遇到过绕过其服务层滥用其域对象的情况?
2个回答

2

我认为你可能误解了POCO的目的。据我所知,POCO不是一个只有属性和属性的贫血域对象。相反,POCO仅仅没有与框架或复杂的继承模型绑定。该对象是灵活的,并且只关心其在域中的角色。


同意Joshua的观点。贫血领域模型被视为一种反面模式,有许多充分的理由支持这种看法。引用Martin Fowler的话:“http://martinfowler.com/bliki/AnemicDomainModel.html”。 - Peter M. Elias

1

它们是两种不同的设计哲学。富领域模型与贫血领域模型。

简短的回答是,是的,您可以防止直接访问您的领域对象。

您可以使用多种技术来实现:

1)您可以通过仅具有getter方法来使所有公共面向领域对象不可变(即无法更改数据)。所有修改对象的方法都可以受到保护或包私有,因此只有正确打包的服务才能访问它们(至少在Java中)
2)您可以仅向外部开发人员公开单独的类--因此,如果您有一个Person领域类,您可以拥有一个PersonInfo类,您传递它,它除了包含信息之外什么也不做。
3)您应向应用程序消费者公开一致的API。您基本上防止他们绕过您的服务层。


#2听起来很像数据传输对象,我想是吧?我猜我可以使用DTO,或者返回一个仅公开我认为最终消费者应该能够设置/获取的属性的接口?我会尝试一些不同的方法。我希望避免使用DTO,因为它们可能会给项目增加另一层复杂性。感谢回复! - Michael McCarthy
@indiecodemonkey,是的,确实如此。但关键是有方法可以锁定API。 - hvgotcodes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接