应用IoC,代码马上直观多了
2007-03-09 12:01
316 查看
IoC在应用开发中是一个非常有力的概念。如Martin Flower所述,IoC的一种表现形式就是依赖性注射。依赖性注射用的是好莱坞原则,"不要找我,我会找你的。"。换句来说,你的类不会去查找或是实例化它们所依赖的类。控制恰好是反过来的,某种容器会设置这种依赖关系。使用IoC常常使代码更加简洁,并且为相互依赖的类提供一种很好的方法。依赖性注射存在三种方式:
a) 基于setter的(setter-based):这些类是特指那些拥有一个无参数的构造器,在绑定依赖关系时提供setter给IoC容器使用的javabean。这是Spring推荐使用的形式。当Spring支持基于构造器的注射时,大量的构造器带的参数就很难管理。
b) 基于构造器的(Constructor-based):这种类拥有带有多个参数的构造器。IoC容器会查找和激活那些基于大量参数和对象类型的构造器。这种方法保证了一个bean不是在一个非法状态下创建的。
c) 基于getter的(Getter-based)或称为方法注射:与基于setter的方式类似,不同的是你为你的添加一个getter方法。当它在内部运行时,IoC容器会重载这个方法,但在测试时你很容易指定你要用的getter方法。这种方法只是在最近被提及到。你可以从TheServerSide.com上找到更多的信息。
下面是一个没有预设IoC一个类的例子。它是一个叫做listUsers的Struts Action,它依赖一个UserDAO类,而这个类需要一个Connection作为构造器的一部分。
public class ListUsers
extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
// get a connection from the database
Connection conn = DatabaseUtils.getConnection();
UserDAO dao = DAOFactory.createUserDAO("hibernate", conn);
List users = dao.getUsers();
DatabaseUtils.closeConnection(conn);
return mapping.findForward("success");
}
}
上面的代码设计比较难看。通过实现一个预设IoC的类把代码清理一下。
public void deleteMudadmUsers(final MudadmUsers mudadmUsers) {
getHibernateTemplate().delete(mudadmUsers);
}
public class ListUsers
extends Action {
private UserDAO dao;
public void setUserDAO(UserDAO userDAO) {
this.dao = userDAO;
}
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
List users = dao.getUsers();
return mapping.findForward("success");
}
}
上面的类没有包含任何查找(lookup)的代码。这样代码看起来更加清晰,并有利于测试。例如,在你的测试中,你可以使用针对DAO使用一个Mock Object来消除数据层的各依赖关系。一个好的IoC容器应该允许开发人员为UserDAO绑定一个连接(connection)(或是DataSource)。使用Spring你可以选择,把连接绑定到数据层,还是使用一个过滤器为每个请求打开一个新的连接。
a) 基于setter的(setter-based):这些类是特指那些拥有一个无参数的构造器,在绑定依赖关系时提供setter给IoC容器使用的javabean。这是Spring推荐使用的形式。当Spring支持基于构造器的注射时,大量的构造器带的参数就很难管理。
b) 基于构造器的(Constructor-based):这种类拥有带有多个参数的构造器。IoC容器会查找和激活那些基于大量参数和对象类型的构造器。这种方法保证了一个bean不是在一个非法状态下创建的。
c) 基于getter的(Getter-based)或称为方法注射:与基于setter的方式类似,不同的是你为你的添加一个getter方法。当它在内部运行时,IoC容器会重载这个方法,但在测试时你很容易指定你要用的getter方法。这种方法只是在最近被提及到。你可以从TheServerSide.com上找到更多的信息。
下面是一个没有预设IoC一个类的例子。它是一个叫做listUsers的Struts Action,它依赖一个UserDAO类,而这个类需要一个Connection作为构造器的一部分。
public class ListUsers
extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
// get a connection from the database
Connection conn = DatabaseUtils.getConnection();
UserDAO dao = DAOFactory.createUserDAO("hibernate", conn);
List users = dao.getUsers();
DatabaseUtils.closeConnection(conn);
return mapping.findForward("success");
}
}
上面的代码设计比较难看。通过实现一个预设IoC的类把代码清理一下。
public void deleteMudadmUsers(final MudadmUsers mudadmUsers) {
getHibernateTemplate().delete(mudadmUsers);
}
public class ListUsers
extends Action {
private UserDAO dao;
public void setUserDAO(UserDAO userDAO) {
this.dao = userDAO;
}
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
List users = dao.getUsers();
return mapping.findForward("success");
}
}
上面的类没有包含任何查找(lookup)的代码。这样代码看起来更加清晰,并有利于测试。例如,在你的测试中,你可以使用针对DAO使用一个Mock Object来消除数据层的各依赖关系。一个好的IoC容器应该允许开发人员为UserDAO绑定一个连接(connection)(或是DataSource)。使用Spring你可以选择,把连接绑定到数据层,还是使用一个过滤器为每个请求打开一个新的连接。
相关文章推荐
- 技术沙龙.:主题为《代码解析Castle(IOC)应用实例 -开源CMS 系统Cuyahoga》
- 技术沙龙.:主题为《代码解析Castle(IOC)应用实例 -开源CMS 系统Cuyahoga》
- 深圳俱乐部10月活动《代码解析Castle(IOC)应用实例 -开源CMS 系统Cuyahoga》
- 技术沙龙.:主题为《代码解析Castle(IOC)应用实例 -开源CMS 系统Cuyahoga》
- Android应用自动更新功能的代码实现
- 中国移动应用内计费平台服务器接口示例代码之“非官方”的一些说明
- php google地图应用实例代码
- Masonry -- 使用纯代码进行iOS应用的autolayout自适应布局
- Ajax类应用示例代码
- Ioc容器应用浅析
- 栈的应用一--斐波那契(Fibonacci)数列的实现(代码)
- java应用——高仿XP画板(四:整个代码)
- 让用户在应用中进入 App Store 打分的代码
- 总结XHTML代码常见的应用问题
- Selenium应用代码(常见封装的方法一)
- Spring中应用java动态代码实现Aop
- php实现简易聊天室应用代码
- Android零基础入门第9节:Android应用实战,不懂代码也可以开发
- GridView级联显示 与Nettier的合成应用Sample[较乱,附代码]
- [原创]ASP.net 2.0 ObjectDataSource 应用操作代码实例(1)-—访问SQL2005