1、耦合

大家可以看以下代碼,jdbc的註冊驅動以及連接資料庫:

在這裡的第一行代碼,大家可以看到,這就有很大的耦合性關係,因為DriverManager依賴於new com.mysql.jdbc.Driver()對象,connection對象依賴於DriverManager,大家可以嘗試一下,如果你把msql的jar包去掉,那麼運行時,在編譯器就出現錯誤。而無法到達運行期。這裡的耦合說的就是一個類依賴於另一個類,如果另一個類涼了,那麼這個類就會在編譯器出錯。

DriverManager.registerDriver(new com.mysql.jdbc.Driver())
Connection conn = DriverManager.getConnection(url,username,password);

所以呢,我們在之前的例子中都是這種註冊驅動,看下面的代碼,這種反射的方式不再是創建一個新對象,避免使用new關鍵字,而是用字元串表示。這樣就降低了耦合性。在編譯器不會出錯。

Class.forName("com.mysql.jdbc.Driver");

耦合是指程序間的依賴關係

它包括 :類之間的依賴、方法之間的依賴解耦:降低程序之間的依賴關係實際開發中:編譯器不依賴、運行時才依賴。

解耦思路:

第一步,使用反射來創建對象,而避免使用new關鍵字第二部:通過讀取配置文件來獲取創建對象的全限定類名

2、舉例

項目目錄

先舉一個耦合性的模擬保存小例子

目錄結構:分別是持久層、業務層、表現層。

IAccountDao介面

package com.spring.dao;
/**
* 持久層
*/
public interface IAccountDao {
void saveAccount();
}

IAccountDaoImpl實現類

package com.spring.dao.Impl;
import com.spring.dao.IAccountDao;
public class IAccountDaoImpl implements IAccountDao {
public void saveAccount() {
System.out.println("保存");
}
}

IAccountService介面

package com.spring.service;
import com.spring.domain.Account;
/**
* 業務層
*/
public interface IAccountService {
void saveAccount(Account account);
}

IAccountServiceImpl實現類

package com.spring.service.Impl;
import com.spring.dao.Impl.IAccountDaoImpl;
import com.spring.domain.Account;
import com.spring.service.IAccountService;
public class IAccountServiceImpl implements IAccountService {
private IAccountDaoImpl accountDao = new IAccountDaoImpl();
public void saveAccount(Account account) {
accountDao.saveAccount();
}
}

Account類就不寫了 就是一個簡單的類

Client表現層

package com.spring.ul;
import com.spring.domain.Account;
import com.spring.service.Impl.IAccountServiceImpl;
/**
* 表現層
*/
public class Client {
public static void main(String[] args) {
IAccountServiceImpl accountService = new IAccountServiceImpl();
accountService.saveAccount(new Account());
}
}

在這裡表現層調用業務層時,使用了new關鍵字,業務層調用持久層時,也使用了new關鍵字。這裡就有耦合性。接下來我們就去解決這個問題。

解決耦合性

創建一個BeanFactory類。

  • 一個創建Bean對象的工廠
  • Bean:在計算機英語中是可重用組件的意思。
  • JavaBean:用java語言編寫的可重用組件。
  • JavaBean > 實體類
  • 它用於創建我們的service和dao對象的。
  • 第一個:需要一個配置文件來配置我們的service和dao。
  • 配置的內容:唯一標識=全限定類名(key = value)。
  • 第二個:通過讀取配置文件中配置的內容,反射創建對象。
  • 配置文件可以是xml文件也可以是propertis文件

1、項目目錄

增加的類。

2、BeanFactory類

在這裡我們用類載入器去讀取配置文件,而不用絕對路徑和相對路徑。之後我們創建一個Map容器,用於讀取配置文件中所有的對象的全限定類名,再利用反射機制創建對象。這個容器保證了無論利用工廠創建多個對象,它永遠指向一個對象,也就是單例思想。

package com.spring.factory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class BeanFactory {
private static Properties props;
private static Map<String,Object> beans;
static{
props = new Properties();
//獲取文件輸入流對象
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
try {
props.load(in);
// 實例化容器
beans = new HashMap<String, Object>();
// 獲取配置文件中的key
Enumeration<Object> keys = props.keys();
// 遍歷枚舉
while(keys.hasMoreElements()){
String key = keys.nextElement().toString();
String beanPath = props.getProperty(key);
Object value = Class.forName(beanPath).newInstance();
beans.put(key,value);
}

} catch (Exception e) {
throw new ExceptionInInitializerError("初始化properties失敗!!");
}
}
public static Object getBean(String beanName){
return beans.get(beanName);
}
}

3、配置文件信息

accountService=com.spring.service.Impl.IAccountServiceImpl
accountDao=com.spring.dao.Impl.IAccountDaoImpl

4、Client類

package com.spring.ul;

import com.spring.domain.Account;
import com.spring.factory.BeanFactory;
import com.spring.service.IAccountService;
import com.spring.service.Impl.IAccountServiceImpl;
/**
* 表現層
*/
public class Client {
public static void main(String[] args) {
IAccountServiceImpl accountService = (IAccountServiceImpl) BeanFactory.getBean("accountService");
accountService.saveAccount(new Account());
}
}

5、運行結果

利用工廠模式加反射機制極大的降低了程序間的耦合性。但是請大家注意,程序間的耦合性不能完全消除。


作者:Zesystem

原文:blog.csdn.net/weixin_44不求打賞 只求關注和點贊

推薦閱讀:

相关文章