我有一个 Java Spring引导应用程序,该应用程序具有图层(包):
在我的
Domain
内部,我有两个数据库类我的
service package
中有很多类,它们同时使用MysqlDBManager
和MongoDBManager
的方法。如果 我直接在我的服务类上使用
MysqlDBManager' and
MongoDBManager`的实例,则服务层将与域层紧密耦合。为了解决这个问题,我在域包中创建了一个名为
**DBManager**
的类,该类充当代理类,该代理类根据内部用例调用MysqlDBManager' and
MongoDBManager`。现在服务层,而不是调用
MysqlDBManager' and
MongoDBManager directly they call
DBManager , which internally calls
MysqlDBManager'和MongoDBManager
。因此,现在我的服务类别与领域层并没有紧密联系。
以下是与用例相似的类。
MongoDBManager类:
Class MongoDBManager {
public saveUserDocs(String docs) {
//.....
}
}
MysqlDBManager类:
Class MysqlDBManager {
public saveUserData(List<String> rows) {
//.....
}
}
DBManager类:
Class DBManager {
@Autowired
private MysqlDBManager mysqlDBManager;
@Autowired
private MongoDBManager mongoDBManager;
public saveUserData(List<String> rows) {
mysqlDBManager.saveUserData(rows);
}
public saveUserDocs(String docs) {
mongoDBManager.saveUserDocs(docs);
}
}
服务类别:
class Service {
@Autowired
private DBManager dBManager;
//....... code here
dBManager.saveUserData(rows);
dBManager.saveUserDocs(docs);
}
我的问题是:
这(如上所述)是使我的应用程序层松散耦合的好方法,还是存在更好的方法呢?
最佳答案
您的方法很好,它看起来像某种Facade设计模式,但我建议您使用更传统的方法。
您已经拥有spring作为IoC容器,因此您所要做的就是从*DBManager
-classes中提取接口,并告诉spring您的实现。然后,您将能够使用接口注入实际的实现,而该接口又可能位于完全不同的包中。因此,耦合将不复存在。
这是一个例子。
数据存储合同:
package root;
import java.util.List;
public interface UserDataStorage {
void saveUserData(List<String> rows);
}
文档存储合同:
package root;
public interface UserDocumentStorage {
void saveUserDocs(String docs);
}
数据存储实现:
package root.domain;
import org.springframework.stereotype.Service;
import root.UserDataStorage;
import java.util.List;
@Service
public class MysqlDBManager implements UserDataStorage {
@Override
public void saveUserData(List<String> rows) {
System.out.println("Saving data....");
}
}
DocumentStorage实现:
package root.domain;
import org.springframework.stereotype.Service;
import root.UserDocumentStorage;
@Service
public class MongoDBManager implements UserDocumentStorage {
@Override
public void saveUserDocs(String docs) {
System.out.println("Saving docs....");
}
}
然后您的服务类可能如下所示(请注意,没有对
domain
包的引用:package root.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import root.UserDataStorage;
import root.UserDocumentStorage;
import java.util.Collections;
@Service
public class MyService {
private final UserDataStorage dataStorage;
private final UserDocumentStorage documentStorage;
@Autowired
public MyService(UserDataStorage dataStorage, UserDocumentStorage documentStorage) {
this.dataStorage = dataStorage;
this.documentStorage = documentStorage;
}
public void callMe() {
this.dataStorage.saveUserData(Collections.emptyList());
this.documentStorage.saveUserDocs("Document1");
}
}