2017-10-10 146 views
5

我有一個爪哇彈簧引導應用程序,它具有層():使應用層鬆散耦合

  • 控制器(控制器類)
  • 服務(業務邏輯)
  • 域(數據庫層)

Inside My Domain我有兩個數據庫類

  • MysqlDBManager
  • MongoDBManager

我在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); 
} 

我的問題是

這是(如上所述)一個很好的方法,使我的應用程序層鬆散耦合或他們的存在更好的方法來做到這一點?

+1

始終遵循SOA(面向服務架構),使應用程序層鬆散的夫婦。 –

+1

看看「命令模式」 – okante

回答

4

恕我直言,有一個更好的方式,界面幫助你有鬆散耦合層,這裏有一個例子:

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); 
} 
+0

哦,整潔的解決方案! –

4

你的做法很好,它看起來像某種Facade的設計模式,但我會推薦更傳統的方式。

你已經有了IoC容器的彈性,所以你所要做的就是從你的*DBManager類中提取接口並告訴Spring你的實現。然後你將能夠使用一個接口注入一個實際的實現,而接口又可能駐留在一個完全不同的包中。因此耦合將不復存在。

這裏是一個例子。

數據存儲合同:

package root; 

import java.util.List; 

public interface UserDataStorage { 
    void saveUserData(List<String> rows); 
} 

DocumentStorage合同:

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"); 
    } 
}