软件项目实训及课程设计指导——如何降低软件系统中程序类之间耦合关系(下篇)
4、应用控制反转(IoC)设计模式减少程序类之间的依赖关系
(1)软件应用系统中各个模块之间产生出依赖关系是不可避免的
软件应用系统中的各个程序类之间通过相互交互和相互协作实现软件应用系统中的各个业务逻辑,因此程序类之间的依赖关系是不可避免的;另外,在软件应用系统中如果应用了某中J2EE应用框架技术(如MVC Struts2框架或者O/R Mapping相关的持久层框架),则软件应用系统和J2EE应用框架之间也不可避免地会产生出相互的依赖关系。
因此,在软件应用系统设计和开发实现中,读者一定要明确:依赖是不可避免的,没有”零”依赖关系的软件应用系统;软件应用系统的设计和开发人员的努力方向是尽可能地减少依赖关系或者根除无意义的依赖关系。
下图所示为银行账户信息管理系统中的业务控制调度Action类继承于MVC Struts2框架中的ActionSupport基类,而使得本银行账户信息管理系统依赖于MVC Struts2应用框架中的API;另外,在Action程序类中还声明有HttpServletRequest、HttpServletResponse和HttpSession等J2EE Servlet API对象,因此也使得本软件应用系统也不可避免地要依赖于J2EE Servlet容器。
(2)依赖倒置原则能够帮助软件应用系统的设计人员减弱程序类之间的依赖关系
通过遵守”依赖倒置原则”不仅可以减弱软件应用系统中各个程序类之间的依赖关系、也能够减弱软件应用系统与J2EE框架系统之间的依赖关系。这是因为,软件应用系统的设计人员是利用J2EE应用框架中所提供的接口,从而隔离了对J2EE应用框架中的具体功能实现类的依赖 。当J2EE应用框架的相关系统程序升级完善时,基本上不会影响到使用该J2EE应用框架的软件应用系统本身。
(3)应用”控制反转”可以消解J2EE应用框架对软件应用系统之间的依赖关系
当然,J2EE系统平台中的各种应用框架系统本身在设计时也必须要考虑到如何减少与用户的软件应用系统之间的依赖关系,为此可以采用”控制反转”(IoC,Inversion of Control)相关的实现技术来解决此类问题。
因为,利用”控制反转”可以消解J2EE应用框架对软件应用系统之间的依赖关系,J2EE应用框架系统通过”控制反转”,反过来对软件应用系统中的功能实现类进行动态回调,最后能达到J2EE应用框架自身可以独立地被重用到不同的软件应用系统中,否则J2EE应用框架就不具有通用性而被应用于不同的软件应用系统中。
(4)利用控制反转设计模式能够减弱代码调用者和被调用者之间的依赖关系
“控制反转”的应用价值不仅体现在可以减少J2EE应用框架对软件应用系统的依赖,也可以将”控制反转”应用于减少软件应用系统内部的程序类之间的耦合关系。也就是应用控制反转设计模式也同样还能够降低软件应用系统内部的各个程序类之间由于相互调用而产生的依赖关系,因为控制反转设计模式是一种让服务的使用者(客户程序)不直接依赖于服务实现的提供者(服务程序)的类之间关系的设计模式。
控制反转设计模式其实是对面向对象程序类设计的五大原则中的”依赖倒置原则”的具体实现。因为如果应用控制反转设计模式,则可以实现由外部容器程序(如J2EE Spring应用框架等)完成对象的创建和生命周期的管理,并在软件应用系统需要该对象的时候再将其所依赖的对象引入到软件应用系统中。
(5)在示例项目中应用控制反转设计模式的应用实例
下图所示的配置文件为银行账户信息管理系统中基于MVC Struts2应用框架实现的某个Action类与显示处理结果的目标页面之间的XML配置定义关系的文件。在常规的J2EE Web Servlet实现技术中,一般是直接将转发的目标JSP页面文件名称以硬编码的方式写入到J2EE Servlet程序类中;而在MVC Struts2应用框架的Action类实现时,则应用控制反转设计模式改变了这样的紧密耦合关系而将转发的目标JSP页面文件名在XML配置文件中定义、并由MVC Struts2应用框架的运行系统程序(也就是IOC容器的系统程序)通过依赖注入的方式提供给目标Action类程序。
这样的系统设计结果,大大地提高了Action类程序的灵活性和适应性,当相关的参数发生变化时不需要修改相关的Action类程序代码,只需要修改对应的XML配置文件。
5、如何在软件应用系统开发中应用依赖注入(DI)技术
由于”控制反转”更多的体现是在”思想” 级别,也就是它是一种”解耦”程序类关系的设计模式或者编程方法,而要真正地让软件应用系统的设计和开发人员能够在实际的软件应用系统项目开发实现中应用控制反转设计模式,一般是通过采用依赖注入(DI,Dependency Injection)的实现技术。
(1)属性注入(Setter Injection)
(2)构造注入(Constructor Injection)
(3)接口注入(Interface Injection)。
对于熟悉J2EE Spring 应用框架的读者来说,上述所提及的属性注入、构造注入和接口注入等依赖注入的实现方式应该不会感到陌生!从本质上来说,依赖注入的具体技术实现其实是充分地应用了Java语言中的反射技术——熟悉J2EE Spring应用框架技术的读者应该对J2EE Spring应用框架中的依赖注入技术的实现方式比较了解。
下图所示的示例图中的程序代码为银行账户信息管理系统中的UserInfoManageAction类程序局部截图,其中基于MVC Struts2应用框架实现的UserInfoManageAction类通过实现ModelDriven接口,然后由MVC Struts2应用框架容器程序将页面表单UserInfoActionForm组件类对象实例注入到相关的UserInfoManageAction程序类中(只需要通过getModel方法获得)代码实现的示图。
6、许多J2EE应用框架都提供了对依赖注入的技术支持
(1)Spring应用框架和Spring MVC框架
目前有许多J2EE应用框架都提供了对依赖注入的具体实现的支持,比如Spring应用框架和Spring MVC框架都全面地提供了对控制反转和依赖注入的支持。如下图所示为Spring MVC框架官方 站上对Spring MVC框架的功能介绍的页面图示。
Spring应用框架全面地提供了对控制反转和依赖注入的支持。下图所示为Spring应用框架官方 站上对Spring应用框架的功能介绍的页面图示,读者可以在该官方 站中下载Spring应用框架相关的系统库文件和技术帮助文档文件等。
(2)Strust2 MVC应用框架
当然,在Apache Strust2 MVC应用框架中同样也提供了对控制反转和依赖注入的支持。下图所示为Apache Strust2 MVC应用框架官方 站上对Strust2应用框架的功能特性介绍的页面图示,读者可以在该官方 站中下载相关的系统库文件和技术帮助文档文件等。
(3)Spring应用框架采用XML配置文件定义对象之间关系及对象运行时的参数
Spring应用框架不仅提供了对控制反转和依赖注入的技术支持,而且还应用外部配置文件定义对象之间关系及对象运行时的参数。如下示图为在某软件应用系统中体现某对象和对象之间关系的Spring配置文件——以外部文件形式设定对象之间相关联的细节。
当然,为了能够在软件应用系统项目中正确地应用控制反转和依赖注入等相关的技术实现,在进行系统开发时对开发人员提出了如下的基本要求:
1)在系统设计方面,要求他设计人员要以面向抽象方式(充分应用面向对象中的抽象和封装等思想)进行软件应用系统的设计,并且软件应用系统中的各个层之间以接口互联。
2)在系统开发实现方面,则要求软件应用系统的开发者在程序代码中不应该再直接创建出目标对象,但是需要在配置文件中描述出创建它们的方式和要求;程序在运行时,由容器 (在 Spring 应用框架中是 IOC 容器)负责将这些对象关联——Spring 应用框架是通过Java反射技术实现”依赖注入”相关的技术。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!