【问题标题】:Make application layer loosely coupled使应用层松耦合
【发布时间】:2017-10-10 17:00:37
【问题描述】:

我有一个 Java Spring-boot 应用程序,它有层():

  • 控制器(控制器类)
  • 服务(业务逻辑)
  • 域(数据库层)

在我的Domain 里面我有两个数据库类

  • MysqlDBManager
  • MongoDB 管理器

我的service package 中有很多类,它们使用MysqlDBManagerMongoDBManager 的方法。

如果 我直接在我的服务类上使用MysqlDBManager' andMongoDBManager`的实例,那么服务层将得到紧密耦合 带有 层。

为了解决这个问题,我在我的 domain 包中创建了一个名为 **DBManager** 的类,它充当代理类,它根据内部用例调用 MysqlDBManager' andMongoDBManager`。

现在服务层,而不是调用MysqlDBManager' andMongoDBManagerdirectly they callDBManager, which internally callsMysqlDBManager'和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);
}

我的问题是

这是(如上所述)使我的应用程序层松散耦合的好方法,还是它们存在更好的方法来做到这一点?

【问题讨论】:

  • 始终遵循 SOA(面向服务的架构)使应用层松散耦合。
  • 看看“命令模式”

标签: java spring oop design-patterns architecture


【解决方案1】:

你的方法很好,它看起来像某种外观设计模式,但我会推荐更传统的方式。

您已经将 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");
    }
}

【讨论】:

    【解决方案2】:

    恕我直言,有一个更好的方法,接口可以帮助您拥有松散耦合的层,这是一个示例:

    interface DocsDBManager {
       void saveUserDocs(String docs);
    }
    
    interface UserDBManager {
       void saveUserData(List<String> rows);
    }
    
    interface DBManager extends DocsDBManager, UserDBManager {
    }
    

    你必须实现它们:

    class  MongoDBManager implements DocsDBManager {
       public void saveUserDocs(String docs) {
         //.....
       }
    }
    
    class  MysqlDBManager implements UserDBManager {
       public void saveUserData(List<String> rows) {
         //.....
       }
    }
    

    还有:

    class  DBManagerBase implements DBManager  {
    
           @Autowired 
           private DocsDBManager docsDBManager;
           @Autowired 
           private UserDBManager userDBManager;
    
           public void saveUserData(List<String> rows) {
                userDBManager.saveUserData(rows);
           }
    
           public void saveUserDocs(String docs) {
               docsDBManager.saveUserDocs(docs);
           }
     }
    

    最后:

    class Service {
        @Autowired 
        private DBManager dBManager;
    
        //....... code here
        dBManager.saveUserData(rows);
        dBManager.saveUserDocs(docs);
    }
    

    【讨论】:

    • 哦,巧妙的解决方案!
    猜你喜欢
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-19
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多