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