模仿spring IOC原理(通過工廠模式和xml文件)

這裏的模仿相比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執行的結果
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章