程序的耦合和解耦
耦合
指的是程序間的依賴關系,包括類之間的依賴和方法間的依賴
解耦
降低程序間的依賴關系,實際開發中應該做到編譯器不依賴,運行時才依賴
解耦的思路
-
使用反射來創建對象,而避免使用new關鍵字
-
通過讀取配置文件來獲取要創建的對象的全限定類名
舉例
下面請看一個簡單的例子,模擬賬號保存
該項目的文件結構如圖
業務層的接口及其實現類:
package com.itheima.service;
/**
* @Author:Zzq
* @Description:賬戶的業務層的接口
* @Date:2020/6/13
* @Time:15:50
*/
public interface iAccountService {
/**
*@Author:Zzq
*@Description:模擬保存賬戶
*@Date:2020/6/13
*@Param: * @param null
*/
void saveAccount();
}
package com.itheima.service.impl;
import com.itheima.factory.BeanFactory;
import com.itheima.mapper.iAccountMapper;
import com.itheima.service.iAccountService;
/**
* @Author:Zzq
* @Description:賬號的業務實現類
* @Date:2020/6/13
* @Time:15:53
*/
public class AccountServiceImpl implements iAccountService {
private iAccountMapper accountMapper = new AccountMapperImpl();
@Override
public void saveAccount() {
accountMapper.saveAccount();
}
}
持久層的接口及其實現類
package com.itheima.mapper;
/**
* @Author:Zzq
* @Description:賬戶的持久層接口
* @Date:2020/6/13
* @Time:16:08
*/
public interface iAccountMapper {
void saveAccount();
}
package com.itheima.mapper.impl;
import com.itheima.mapper.iAccountMapper;
/**
* @Author:Zzq
* @Description:賬戶的持久層實現類
* @Date:2020/6/13
* @Time:16:10
*/
public class AccountMapperImpl implements iAccountMapper {
public void saveAccount(){
System.out.println("保存了");
}
}
最后是main函數,也是其表現層
package com.itheima.ui;
import com.itheima.factory.BeanFactory;
import com.itheima.service.iAccountService;
/**
* @Author:Zzq
* @Description:模擬一個表現層,用於調用業務
* @Date:2020/6/13
* @Time:22:28
*/
public class Client {
public static void main(String[] args) {
AccountServiceImpl as = new AccountServiceImpl();
as.saveAccount();
}
}
從代碼中可以看到,各個層次是相互依賴,層層套用,這樣就稱之為高耦合,各個代碼塊之間獨立性較差,下面就按照解耦的思路來盡可能降低耦合,如下:
1.在項目文件中新建一個factory包,新建一個BeanFactory類來建立一個bean工廠來創建我們的service和mapper對象,並寫好Bean.properties配置文件
package com.itheima.factory;
import java.io.InputStream;
import java.util.Properties;
/**
* @Author:Zzq
* @Description:是一個創建bean對象的工廠
*
* Bean:在計算機英語中,有可重用組件的含義。
* JavaBean:用Java編寫的可重用組件。
* Java >> 實體類
* 它就是創建我們的service和mapper對象的。
* 1.需要一個配置文件來配置我們的service和mapper
* 配置的內容:唯一標識 = 全限定類名(key = value)
* 2.通過讀取配置文件的配置內容,反射創建對象
*
* 配置文件可以是xml也可以是properties
* @Date:2020/6/13
* @Time:22:36
*/
public class BeanFactory {
//定義一個properties對象
private static Properties props;
//使用靜態代碼塊為Properties對象賦值
static {
try {
//實例化對象
props = new Properties();
//獲取properties文件的流對象
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
}catch (Exception e) {
throw new ExceptionInInitializerError("初始化properties失敗");
}
}
/**
*@Author:Zzq
*@Description:根據bean的名稱獲取bean對象
*@Date:2020/6/13
*@Param: * @param null
*/
public static Object getBean(String beanName){
Object bean = null;
try {
String beanPath = props.getProperty(beanName);
bean = Class.forName(beanPath).newInstance();
}catch (Exception e){
e.printStackTrace();
}
return bean;
}
}
accountService = com.itheima.service.impl.AccountServiceImpl
accountMapper = com.itheima.mapper.impl.AccountMapperImpl
2.修改Client.java和AccountServiceImpl.java代碼,使用反射來創建對象
package com.itheima.ui;
import com.itheima.factory.BeanFactory;
import com.itheima.service.iAccountService;
/**
* @Author:Zzq
* @Description:模擬一個表現層,用於調用業務
* @Date:2020/6/13
* @Time:22:28
*/
public class Client {
public static void main(String[] args) {
iAccountService as = (iAccountService) BeanFactory.getBean("accountService");
as.saveAccount();
}
}
package com.itheima.service.impl;
import com.itheima.factory.BeanFactory;
import com.itheima.mapper.iAccountMapper;
import com.itheima.service.iAccountService;
/**
* @Author:Zzq
* @Description:賬號的業務實現類
* @Date:2020/6/13
* @Time:15:53
*/
public class AccountServiceImpl implements iAccountService {
private iAccountMapper accountMapper = (iAccountMapper) BeanFactory.getBean("accountMapper");
@Override
public void saveAccount() {
accountMapper.saveAccount();
}
}
以上就是解耦的過程,在使用了BeanFactory了之后,就算是刪除掉了service或mapper文件,編譯器也不會報錯,有人看到這里肯定會說:啊,你這不是脫褲子放屁嘛,明明幾個類就能解決的問題非要弄個工廠?其實是這個例子太高簡單,還不足以看出低耦合的好處,在以后比較大型的開發中,如果有新的需求要加入,我們就可以只添加幾個類就能完成,而不用重新考慮整個程序,避免牽一發而動全身。