程序的耦合
我們基礎學習時,創建一個對象往往是通過new的方式,這樣就必須導這個.class文件的所屬jar包。這樣造成的後果就是程序耦合行太強,如果我們沒有導這個包,在編譯期就會給我們報出錯誤,這是我們不想看見的。我們應該做到的是在編譯期各個文件不依賴,運行時才依賴。
- 耦合:程序間的依賴關係(包括類與類、方法與方法之間)
- 解耦:降低程序間的依賴關係
- 解耦思路:
> 使用反射來創建對象,而避免使用new關鍵字
> 通過讀取配置文件來獲取要創鍵的對象的全限定類名
BeanFactory
BeanFactory字面意思就是創建bean的一個工廠。
- bean:可重用組件的含義,如service、dao層的對象
- JavaBean:用Java語言編寫的可重用組件,範圍是大於實體類的,並不是單指domain包中的一下實體類。
創建BeanFactory
以創建我們常用的的service和dao對象爲例。
爲了更爲降低耦合性,我們可以在準備一個配置文件來配置我們的service和dao,配置的內容:唯一標識=全限定類名(key=value),通過讀取配置文件中配置的內容,反射創建對象,我的配置文件可以是xml也可以是properties。
bean.properties
userService=com.baidu.service.impl.UserServiceImpl
userDao=com.baidu.dao.impl.UserDaoImpl
BeanFactory.java
public class BeanFactory {
//定義一個Properties對象
private static Properties props;
//定義容器,用於存放我們要創建的對象。
private static Map<String,Object> beans;
//使用靜態代碼塊爲Properties對象賦值
static {
try {
//實例化對象
props = new Properties();
//獲取properties文件的流對象
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
//實例化容器
beans = new HashMap<String,Object>();
//取出配置文件中所有的Key
Enumeration keys = props.keys();
//遍歷枚舉
while (keys.hasMoreElements()){
//取出每個Key
String key = keys.nextElement().toString();
//根據key獲取value
String beanPath = props.getProperty(key);
//反射創建對象,每次都會調用默認構造函數創建對象
Object value = Class.forName(beanPath).newInstance();
//把key和value存入容器中
beans.put(key,value);
}
}catch(Exception e){
throw new ExceptionInInitializerError("初始化properties失敗!");
}
}
/**
* 根據bean的名稱獲取對象
* @param beanName
* @return
*/
public static Object getBean(String beanName){
//直接獲取map的key值拿到對象
return beans.get(beanName);
}
}
測試一下
public class Test {
public static void main(String[] args) {
//根據配置文件的鍵值,獲取對象
IUserService as = (IUserService) BeanFactory.getBean("userService");
System.out.println(as);
as.findAll();
}
}
我們這是一個單例模式的BeanFactory,每次獲取的是同一個對象。對於線程安全問題暫時不考慮,不過好像service、和dao中往往創建的對象都會是無狀態變量,