这里的模仿相比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执行的结果