[老文] 从工厂模式到IoC容器

http://blog.lidaobing.info/2008/12/ioc.html
1. 通过数据层访问数据库 


最简单的模型,采用一个数据访问层,来隔离应用与数据库。
public class MyDA {
//...
}

public class MyApp {
public MyApp() {
da = new MyDA();
}
private MyDA da;
//...
}

2. 面向界面编程,同时方便使用 Mock 方法测试

public interface IMyDA {
//...
}


public class MyDA implements IMyDA {

//...
}

public class MyApp {
public MyApp() {
setDA(new MyDA());
}
protected void setDA(IMyDA da) {
this.da = da;
}
private IMyDA da;
//...
}



关于 Mock 测试,参见 http://www.ibm.com/developerworks/library/j-mocktest.html

3. 引入工厂模式,隔离数据访问与业务逻辑



public interface IMyDA {
//...
}

public class MyDA implements IMyDA {
//...
}

public class MyDAFactory {
public IMyDA createMyDA(String name) {
if(name.equals("foo")) {
return new MyDA();
} else {
throw new Exception();
}
}
}


public class MyApp {
public MyApp() {
setDA(MyDAFactory.createMyDA("foo"));
}
protected void setDA(IMyDA da) {
this.da = da;
}
private IMyDA da;
//...
}



这种情况下 MyApp 仍然通过 MyDAFactory 来依赖与 MyDA, 甚至各种 IMyDA 的实现。另外,工厂模式不方便添加新的实现。



4. 引入 IoC 容器 


Java 源码部分



public interface IMyDA {
//...
}

public class MyDA implements IMyDA {
//...
}


public class MyApp {
public MyApp() { 
BeanFactory factory = new XmlBeanFactory(
new FileInputStream("myapp.xml"));

da = (IMyDA) factory.getBean("da");
}

private IMyDA da;

//...
}

用到的 myapp.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="da" class="MyDA"/>
</beans>

5. 一个复杂点的例子


上面的例子有点小题大做了,在真实的环境中,数据访问一般需要通过 MySQL库, 连接池, cache, 甚至更多的层,每一层都需要可以配置,最好也支持替换(方便测试),设置还需要支持删除某些中间层,工厂模式用于这样的情形则非常麻烦,但是 IoC 处理这样的情形则比较简单,比如把如下的文件替换掉上面的myapp.xml,那么你的应用的数据访问层就变成了用于数据库连接池和cache功能的 SuperMyDA。



更重要的是,隔离非常彻底,在你编写编译 MyApp 的时候,你根本就用不着 proxool, memcache 这类组件。



注意: 下面文件里面的内容都是乱写的,我还没去查这些组件的接口, :-)



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<!-- 配置 mysql 连接 -->
<bean id="db" class="com.mysql.Connection">
<property name="uri"
value="mysql://userName:secret@192.168.12.23/dbname"/>
</bean>

<!-- 配置 proxool -->
<bean id="proxool" class="com.proxool.Pool">
<property name="db" ref="db"/>
<property name="maxConnection" value="200"/>
</bean>

<!-- 配置 memcache -->
<bean id="memcache" class="com.memcache.Foo">
<property name="config" value="192.168.23.34:12345">
</bean>

<!-- 配置 SuperMyDA -->
<bean id="da" class="SuperMyDA">
<property name="proxool" ref="proxool"/>
<property name="memcache" ref="memcache"/>
</bean>

</beans>
posted @ 2011-05-19 14:52  LI Daobing  阅读(1279)  评论(0编辑  收藏  举报