這裏的模仿相比spring要簡單的多了,只是一種思想,通過工廠模式和xml配置文件降低程序的耦合性。
IOC,它是Inverse of Control的縮寫,中文含義是控制反轉,表示將對象的創建權力反轉給Spring框架!意思就是將創建對象的權利給Spring,而不是我們自己在類裏寫new一個對象
IOC解決的問題:使用IOC可以解決的程序耦合性高的問題!!
那麼什麼是程序的耦合呢?
我們在開發中,會寫很多的類,而有些類之間不可避免的產生依賴關係,這種依賴關係稱之爲耦合。有些依賴關係是必須的,有些依賴關係可以通過優化代碼來解除的。先看下下面代碼
解耦前
dao層
dao層接口
public interface UserDao {
public void save();
}
dao層實現類1
public class UserDaoImpl implements UserDao{
@Override
public void save() {
System.out.println("持久層:用戶保存11111");
}
}
dao層實現類2
public class UserDaoImpl2 implements UserDao{
@Override
public void save() {
System.out.println("持久層:保存2222");
}
}
service層
service層接口
public interface UserService {
public void save();
}
service層實現類
public class UserServiceImpl implements UserService {
@Override
public void save() {
UserDao userDao = new UserDaoImpl();
userDao.save();
}
}
test測試類
public class TestIOC {
@Test
public void test1(){
UserService service = new UserServiceImpl();
service.save();
}
}
從上面代碼來看,UserServiceImpl實現類和UserDaoImpl實現類耦合度較高,比方說,我們現在要調用UserDaoImpl2下的方法的話,需要將service層代碼作如下修改才能滿足我們的要求,怎麼在不修改源碼的情況下實現這樣的功能?下面看下工廠模式和xml配置文件的配合使用
解耦後
xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<bean id="userDao" class="cn.itcast.dao.impl.UserDaoImpl"></bean>
工廠類
public class BeanFactory {
//從xml中解析bean,通過反射的到的對象存到map中
private static Map<String, Object> map = new HashMap<String, Object>();
static {
try {
//創建sax讀取對象
SAXReader saxReader = new SAXReader();
//讀取XML文件,獲得文件對象
Document document = saxReader.read(BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml"));
//讀取xml文件下的根節點
Element root = document.getRootElement();
//獲取id屬性的對應的值
String id = root.attributeValue("id");
//獲取類全限定名
String clazz = root.attributeValue("class");
//通過反射生成對象
Object object = Class.forName(clazz).newInstance();
map.put(id, object);
} catch (Exception e) {
e.printStackTrace();
}
}
// 獲取實現類對象
public static Object getBean(String id) {
return map.get(id);
}
}
注意點
修改後的service層
public class UserServiceImpl implements UserService {
@Override
public void save() {
UserDao userDao = (UserDao) BeanFactory.getBean("userDao");
userDao.save();
}
}
結果展示
現在只需要修改xml裏類的全限定名,程序就會執行不同的對象,實現了不需要修改的代碼的情況,進行功能切換,請看下圖
調用UserDaoImpl執行的結果
調用UserDaoImpl2執行的結果