【发布时间】:2016-11-24 07:44:09
【问题描述】:
由于数据库的设计,我有相当多的JpaRepository 扩展存储库接口。
为了构造一个简单的对象,即Person,我必须对大约 4 - 5 个存储库进行方法调用,因为数据在整个数据库中都是这样分布的。像这样的东西(请原谅伪代码):
@Service
public class PersonConstructService {
public PersonConstructService(Repository repository,
RepositoryTwo repositoryTwo,
RepositoryThree repositoryThree) {
public Person constructPerson() {
person
.add(GetDataFromRepositoryOne())
.add(GetDataFromRepositoryTwo())
.add(GetDataFromRepositoryThree());
return person;
}
private SomeDataTypeReturnedOne GetDataFromRepositoryOne() {
repository.doSomething();
}
private SomeDataTypeReturnedTwo GetDataFromRepositoryTwo() {
repositoryTwo.doSomething();
}
private SomeDataTypeReturnedThree GetDataFromRepositoryThree() {
repositoryThree.doSomething();
}
}
}
PersonConstructService 类使用所有这些接口只是为了构造一个简单的Person 对象。我从PersonConstructService 类中的不同方法调用这些存储库。我曾想过将这个类分散到多个类中,但我认为这是不正确的。
相反,我想使用repositoryService,其中包括创建Person 对象所需的所有存储库。这是一个好方法吗?春天可以吗?
我问的原因是有时注入服务的数量约为 7-8。这绝对不好。
【问题讨论】:
-
使用 Spring,您可以首先使用
@Autowired批注让您的服务准备好在您的课程中使用,但您不应该直接从您的课程PersonConstructService调用 repositories 方法。没问题,如果你的班级需要 7 个服务,为什么调用这 7 个服务不好呢?而且我猜如果您的 POJO 与 (@ManyToOne,@OneToMany, ...) 之类的关系绑定在一起,您可以简单地构造您的对象而无需手动添加其他对象。 -
@Alex 好吧,如果您的类构造函数中有这么多服务,据我所知,根据 Spring Docs 的代码味道:
As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.您是否建议通过以下方式进行字段注入:With Spring you can at first use @Autowired annotation to get your services ready-for-use in your class? -
完全可以。构造函数参数是一回事,但注入你的服务是另一种正确地做你想做的事情的方法。 Java EE 已经在 v6 中使用
@Inject实现了这一点,Spring 官方关键字是@Autowired,我个人在我的一些类中有时会有 6 或 7 个。我从未见过特定问题 -
@Alex 它会起作用,但你不能确定你的服务不为空。通过构造函数注入,这些东西在编译时被检查。虽然您无法确定字段。
-
Appart 从构造函数与 setter 论点出发,我确实认为您的示例代码设计得很好。您有将数据库表映射到对象概念的存储库。您在其之上使用服务层来构造更多抽象的域对象。这对我来说看起来不错你的“人”抽象需要构建许多存储库这一事实是另一个问题(你的数据库模型化是否足够?)。但考虑到它是什么,在我看来,在服务层聚合 DAO/存储库以构建高级业务模型抽象实际上是一种很好的做法。
标签: java spring spring-data spring-data-jpa