应用程序服务层调用数据库功能。架构不好?


11

场景:

  • 堆栈:Java,Spring,Hibernate。
  • 型号:客户端-服务器应用程序。
  • 模式:模型-视图-控制器(MVC)。

服务层类具有三种行为:

  1. 一些服务在方法内具有业务规则,并将持久性委托给应用程序。喜欢:

    EntityManager.save(entity);

  2. 一些服务只是调用数据库函数(传递参数),例如:

    CallableStatement cls = con.prepareCall(“ {call databaseFunction(args)}”);

  3. 某些服务同时具有两种行为的方法。

我的问题:

  1. 让应用程序服务直接调用数据库功能有什么问题吗?这不是不好的做法吗?适用于这样的项目的架构模型是什么?
  2. 在同一服务中混合行为是否有问题?如交易和一致性?
  3. 在维护的情况下,这种封装是否使开发人员不清楚他也应该更改数据库中的功能?如何避免这种情况?
  4. 这种情况是否会在世界各地的其他应用程序中发生,或者仅仅是架构错误?

这个问题是相似但不完全相同的.. softwareengineering.stackexchange.com/questions/180012/...
乔恩·雷诺

Answers:


7

让应用程序服务直接调用数据库功能有什么问题吗?这不是不好的做法吗?

我认为有。您正在将有关数据库内部的知识放置到应用程序服务中。以任何方式更改数据库(更改存储引擎,甚至重命名字段或创建索引)都可能需要您更改应用程序服务,这违反了SRP

适用于这样的项目的架构模型是什么?

请参阅下面的评论。

在同一服务中混合行为是否有问题?如交易和一致性?

我不相信有技术上的问题,但是有逻辑上的问题。您只需在应用程序中混合使用两种方法,即可使其模糊,结构化,难以适应更改。另请参阅上面有关违反SRP的评论。

在维护的情况下,这种封装是否使开发人员不清楚他也应该更改数据库中的功能?

当然可以。

如何避免这种情况?

将直接与数据库一起使用的方法和函数放置到单独的抽象级别中(是DAO层还是简单的存储库模式-取决于应用程序的复杂性)

这种情况是否会在世界各地的其他应用程序中发生,或者仅仅是架构错误?

我认为我们世界上的一切都会发生;)


如果我理解正确,则可能存在一个技术问题,即如果在函数/存储过程中以及通过ORM进行更新,则很难推断给定事务的状态。尽管应用程序可能会在当前状态下运行,但进行小的更改可能会引发一些非常大的问题。我对Hibernate的经验是,如果您不让它管理与其一起使用的整个表集,则会遇到很多烦人的问题。
JimmyJames

简洁明了的答案。当我第一次查看代码时,SRP是我想到的第一件事。一些同事说,该方法没有违反SRP,因为它只调用数据库函数。但是其中一些功能确实会进行选择,插入和更新。那么它是否违反了SRP?(也许这本身就是另外一个要讨论的问题?)
linuxunil '16

1
我认为我们世界上的
linuxunil 2016年

@linuxunil SRP应该在所有体系结构级别上得到尊重。就我而言,我指的是服务级别的SRP,而不是方法级别的SRP。@ JimmyJames是的。大多数ORM在存储过程中均无法正常工作。但是有时需要存储过程。
Vladislav Rastrusny

3

根据您所说的,有一个服务层,因此看起来合适的架构模式是分层架构。进一步参考

是的,在数据​​访问层以外的另一层上直接进行数据库调用通常是一种不好的做法,这样业务层只能访问数据库的抽象。

至于混合行为,使用某些设计模式作为DAO模式或存储库模式可以帮助委托该职责,从而改进该代码。

使用设计模式和ORM的一些优点是代码的可读性和职责的封装,因此,如果数据库访问发生更改,则业务层应该不会有太大变化。


不知道为什么这被否决了。该答案建议分离处理不同问题的代码。感觉就像是这里的编程负责人……不确定它是什么……伙计。如果我能想到这个名字。+1 BTW
格雷格·伯格哈特

这不是牢固的原则之一吗?
J. Pichardo

3
号的“S”中的固体的小号英格尔责任委托(SRP)。但是,建议您使用关注点分离是将服务逻辑与数据访问逻辑分离的有效理由。弗拉迪斯拉夫(Vladislav)的另一个回答提到了“单一责任负责人”。坦率地说,SRP和关注点分离可以很好地配合使用,就像葡萄酒和奶酪一样。
格雷格·伯格哈特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.