IOC模式范文

2024-07-15

IOC模式范文(精选4篇)

IOC模式 第1篇

当前应用较广泛的接口驱动设计模式通常采用的方法是:首先, 定义一个接口类或抽象类;然后, 从接口类或抽象类派生出新的子类, 实现其抽象方法;接着, 实例化子类并将实例对象赋值给接口类型的变量。该模式有很多优点, 如复用性和扩展性较好, 符合软件设计的开闭原则[1]。这种模式也存在着一些缺点, 如隔离了使用者和实现者之间的依赖关系, 但创建具体实现类的实例对象时仍会造成对具体实现的依赖, 使系统对环境的适应性方面存在不足。

基于接口驱动模式的公文传阅系统在系统部署时就有组件之间存在依赖, 即组件之间存在耦合。例如, 当保存用户信息的数据库由Oracle变成SQL Server, 那么就要对数据库连接组件进行修改, 重新对整个框架进行编译。

2、IOC模式

IOC的全称是Inversion of Control, 即反转控制或依赖注入。IOC的核心思想是:切断服务类对其依赖的接口具体实现类的直接联系, 服务类不直接创建依赖的具体对象, 而由IOC容器来注入。IOC模式的代码不直接与对象和服务连接, 而是通过配置文件描述组件之间的相互依赖关系, IOC容器负责将这些依赖组装在一起。

3、公文传阅系统的IOC容器设计

公文传阅系统的IOC容器主要由一个XML语言的配置文件和一个产生实例对象的工厂类这两个部分组成。

3.1 配置文件的设计

配置文件主要是通过XML的描述, 对接口和接口派生出来的实现类的对应关系进行映射以及对实例对象的构造参数进行设置。如:对于公文传输的服务器类server的描述

3.2 工厂类的设计

IOC容器的工厂类主要是根据配置文件中接口和派生类的映射关系, 利用面向对象的反射技术, 对来产生相应的实例对象, 其实现如下:

4、公文传阅系统中IOC容器的使用

在公文传阅系统中可以通过IOC容器方便的注入组件。如要对服务器类实例化可以通过:Server server= (Server) ObjectFactory.getObject ("server") 来实例化, 当服务器的端口或IP地址发生变化时, 只要该修改配置文件就可以。同样如果想获取Dao层组件时可以通过:dbstore db= (dbstore) ObjectFactory.getObject ("dbstore") 来实现, 当数据库发生变更, 可以重新定义一个Dao层接口的实现类, 编译后添加到相应的Jar包中同时修改配置文件中"implement"的原始值就方便移植了。

5、总结

基于IOC模式的公文传阅系统可以实现将组件间的依赖关系部署到IOC框架中, 如此降低了系统组件间的耦合程度, 组件之间的依赖关系由IOC容器注入, 如果某一组件发生了变更, 那么只要改变IOC容器的配置文件就可以了, 同时该模式也具有接口驱动模式的优点。

参考文献

[1].苏琨.基于Ioc模式的软件开发框架重构.山西电子技术.2006, [2]:82~83, 94

[2].魏学松, 张育平.IOC框架的研究与设计.计算机技术与发展, 2006, 16[3]:213~216

IoC原理浅析 第2篇

因此, 模块之间必定会有这样或那样的依赖关系, 过强的耦合关系 (如一个模块的变化会造成一个或多个其他模块也同时发生变化的依赖关系) 会对软件系统的质量造成很大的危害。特别是当需求发生变化时, 代码的维护成本将非常高。所以, 必须控制和消解不必要的藕合, 特别是那种会导致其它模块发生不可控变化的依赖关系。IoC、DI (依赖注入) 等方法就是开发者仔细研究依赖关系, 经过许多设计实践后发展起来的新方法。

一、IoC原理

在传统的模块实现中, 由程序代码直接控制程序之间的关系。而加入了IoC设计概念后, 意味着将你设计好的类交给系统去组装控制, 而不是在你的类内部控制, 这称为控制反转 (Inversion of Control, IoC) 。对于框架而言就是由容器控制程序之间的关系, 而非传统实现中由程序代码直接操控。这就是“控制反转”的概念的本意, 即控制权由应用代码中转到了外部容器, 控制权发生了转移所以称为反转。

IoC框架就是将对象的创建和获取提取转移到外部容器, 由外部容器提供需要的组件。对于Spring这样的轻量级容器, 它们的反转是“如何定位插件的具体实现”。这里的“插件”就是实现具体业务逻辑的组件, 它是在程序的运行期间而不是编译期间插入到应用程序当中去的。只要插件遵循一定的规则, 一个独立的组装模块就能够将插件的具体实现“Injection”到应用程序中, 把这种做法的模式叫做“依赖注入 (Dependency Injection, DI) ”。依赖注入就是将组件间的依赖关系提取到组件的外部, 由容器来实现依赖关系的注入, 从这方面讲, 这里将实现控制反转 (IoC) 与依赖注入框架认为是同等的。

实现IoC完成依赖注入的关键技术是“反射机制”。Java语言产生的最根本的目的是为了适应网络应用。Java语言中的反射机制的制定与实施, 其本意是为了能够在网络中传递对象, 并能够根据所传递的对象信息, 重构对象本身, 所以这种重构是动态的。反射机制对于RPC和RMI (远程过程和远程方法调用) 功能的实现起到了巨大的作用。在Java语言中, 一个类具有的各个属性和方法, 通过其它相关的类用以实现对其信息的提取和重构, 这些类都集中在java.lang.reflect包中, 如Field类提供了动态操作一个类或接口中的某个属性的信息, 并且这种属性既可能是某个类的属性, 也可能是某个类实例的属性。Method提供了操作某个类或实例的方法的信息。

Java反射机制的根源是Java中所有类的共同继承的父类Class类, 此类的实例代表了应用程序中的某个类或接口, 在编译Java类的时候, 关于Class类的相关信息就写入编译的类中。Class提供了动态装载某个类的能力, 而这种装载过程依赖于两个因素:JVM (Java虚拟机) 和在编译过程中附加于某个类上的信息。如果有Class动态装载某个类, JVM就首先到内存中寻找这个类, 如没有找到, 则按照系统所设定的classpath到外存上去寻找此类, 并执行相应的加载。Class提供了动态提取内存中相应类的各种元素的方法。若想得到某个类的所有Fields, 可以使用“类实例.getClass () ”, 得到此类的Class对象, 然后利用Class对象的getFields方法得到这个类的所有公有属性。所有属性构成了Field域。Field方法提供的getName () 方法可以得到通过“字段名.get (类实例) ”得到此字段的值。而Class提供的方法getName) 则能够得到某个字段合原始数据类型的名称, 如果字段属于某个类, 则得到类的名字。如此周而复始, 可以追踪所有的相关联的类的字段。

使用反射机制, 可以让容器在编译时并不关注具体的功能, 具体的功能可以通过配置在运行时动态的得到, 这样就可以十分灵活地增加需求。但与此同时系统的性能受到了影响, 为了系统的可维护性和可扩展性, 做出这种取舍是非常适当的。目前许多容器 (如Spring和Hibernate) 的底层都是采用这种技术。

二、依赖注入的几种形式

(一) 接口注入

接口注入其核心思想是借助接口来将调用者与实现者分离。如下面的代码所示:

类A依赖于InterfaceB的实现, 在编译期间A只依赖于InterfaceB, 在运行时根据预先在配置文件中设定的实现类的类名动态加载实现类, 并通过InterfaceB强制转型后为类A所用, 实现了调用者与实现者在编译期分离。Typel型IoC容器加载接口实现并创建其实例的工作由容器完成, 如J2EE开发中常用的Context.lookup (ServletContext.getXXX) 。

(二) 设值方法注入

设值注入方式就是通过JavaBean构件模型中的setter方法传入被调用者的实例, IoC容器通常通过XML文件中的配置信息完成组件的配置。设值注入模式是Spring鼓励采用的方式, 在实际开发中得到了最广泛的应用。相应的实现代码如下:

(三) 构造子注入

构造子注入是通过类的构造函数来完成依赖关系的设定, 一个著名的轻量级容器PicoContainer就是利用这种方法完成依赖注入的。如下面的代码示:

可以看到, 在Type3类型的依赖注入机制中, 依赖关系是通过类构造函数建立, 容器通过调用类的构造方法, 将其所需的依赖关系注入其中。

三、依赖注入方法的比较

由于接口注入模式要求组件必须与特定的接口相关联, 因此并不被看好, 实际使用有限。

设值注入和构造子的依赖注入实现模式均具备无侵入性的特点, 所谓的“无侵入性”就是代码中不需要涉及框架的专有类, 即可将其被框架容器进行管理。

设值注入的优点:setter方法设定的依赖关系与JavaBean的setter设值方法比较相近, 对于用惯了JavaBean的开发者来说比较自然;设值注入的方法比较直观简洁;与第三方类库的冲突可能性减小。

构造子注入方法的优点有:“在构造期即创建一个完整、合法的对象”, 对于这条Java设计原则, 构造子注入方法无疑是这条原则的典型样板。由于没有setter方法, 依赖关系在构造时由容器一次性设定, 因此组件在被创建之后即处于相对“不变”的稳定状态, 无需担心上层代码在调用过程中执行setter方法对组件依赖关系产生破坏。由于关联关系仅在构造函数中表达, 只有组件创建者需要关心组件内部的依赖关系。对调用者而言, 组件中的依赖关系处于黑盒之中。对上层屏蔽不必要的信息, 也为系统的层次清晰性提供了保证。可见设值注入和构造子注入各有优势, 理论上应以构造子注入为主, 值注入为辅, 可以达到比较好的注入效果。但在基于Spring框架开发的系统中, 大都采用值注入方法。使用Ioc模式与框架可提供种新的机制管理业务对象及其依赖关系, 可以降低代码耦合, 使依赖外置化, 可以在统一的地方管理依赖, 从而有效地降低软件开发问题的复杂度、减小维护的代价。

摘要:文章详细分析了IoC设计模式的原理, 讨论了依赖注入的3种方式并对每种方式特点进行了阐述和对比, 最后说明了IoC实际作用。

关键词:控制反转,依赖注入

参考文献

[1]、Gulzar N, Kartik.Practical J2EE Application architecture[M].The McGraw-Hill Companies, 2003.

IOC模式 第3篇

关键词:MVC架构设计,Spring框架,控制反转,IoC容器,解耦

控制反转模式是Spring中的一种框架设计模式,利用这种模式,可以使软件开发框架具有组件间松散耦合、可扩展性高和可复用性高等优点。将这种机制引入Spring MVC的设计中,利用Spring的Bean工厂模式及控制反转功能设计MVC框架,可以提高控制层、业务层及数据层的可维护性和灵活性,为程序员提供了统一的模板化操作。

1 Spring MVC体系结构分析

Sprin g框架提供了构建Web应用程序的全功能M VC模块,使用其可插入的M VC架构,可以选择是使用内置的Spring Web框架还是Struts这样的Web框架。Spring MVC围绕Dispatcher Servlet来进行设计,它是Spring MVC中的前端控制器,负责分发请求到具体的Spring Controller中,由Controller负责对具体请求的处理,并返回处理结果[1]。Spring MVC体系结构如图1所示。

从图1可以很清晰地看到Spring MVC的处理过程:Dispatcher Servlet负责接收用户发送的HTTP请求,并通过Handle Mapping的映射作用将请求分发给Controller;Controller通过委派其他的Java Bean完成具体的处理,即图中的Web Application Context(s)部分;Controller处理完之后,返回Mode And View对象,由Dispatcher Servlet调用视图解析器View Resolver渲染视图并返回给客户端。

2 Io C控制反转功能的实现

在对ORM的支持中,Spring体现了其工作核心—利用Io C容器实现Bean的装配与控制。Spring的Controller和请他对象一样,也是通过Io C来配置的[2]。如果以一个用户身份验证的实例模拟这个工作核心,其过程如图2所示。业务控制器从Io C容器中取回的业务逻辑组件已经是完全装配好的成品Bean,在业务逻辑组件中不用再创建DAO组件了。这种基于Bean容器的实际模式,使控制层、逻辑层及数据层实现充分解耦,可以提高可测试性和可维护性[3]。其中“Bean工厂装配过程”实现了控制权的转移,将原本在控制层和业务层创建对象的过程转移到了自身环节,使得控制权发生了反转,应用本身不再负责依赖对象的创建及维护,而是交由外部容器负责。这样一来,利用Spring框架的特性将业务逻辑对象和数据访问对象交给Io C容器管理,降低了对象之间的依赖程度[4]。

3 应用实例开发

依据图2所示,利用用户身份验证的实例来剖析Spring MVC中的Io C控制过程,采用My SQL作为后台数据库。

3.1 解析配置文件

视图部分在提交数据后,将请求提交给前端控制器Dispatcher Servlet进行处理;这个控制器则根据Spring MVC的配置文件寻找对应的Controller组件,进行逻辑处理后,解析成对应的视图。涉及到的两个配置文件如下:

3.1.1 web.xml配置文件

web.xml建立了“*.do”请求到前端控制器的映射,并设置了Spring MVC配置文件的名称和路径,为Io C容器的管理做好了准备工作,生成的代码如下:

3.1.2 Dispatcher-servlet.xml配置文件

这个配置文件依然遵循b e a n容器的管理模式。Simple Url Handler Mapping实现了Handler Mapping接口,通过key指定URL模式,然后引用Controller类型的bean,完成具体的处理工作。配置文件的核心代码如下:

3.2 实现各层的代码功能

图2已经从控制层、业务层、数据访问层及Io C反转控制层等方面展示了较完整的项目开发结构,并且给出了明确的程序类名及功能描述,只要依据图示建立相关文件,完善代码即可。实现过程中的核心问题有以下两点。

3.2.1 业务控制层

对应的类继承Simple Form Controller,该类非常适合处理表单提交事件,只需重写它的on Submit()方法即可,核心代码如下。其中省略的代码为控制逻辑,依据user List对象的结果进行视图模型的解析。

3.2.2 外部容器的设计

图2中Bean工厂的第一行代码获取了User DAO对象,为后面的bean装配做好准备。那么factory对象是怎样得到的呢?实际上完整的代码应该如下:

基于“面向接口编程”的指导思想,Bean Factory被定义为接口,Xml Bean Factory是该接口最常用的实现类,这个类通过装载指定的XML配置文件实例化Bean Fatory容器[5]。

依照MVC的层次结构和图2所示,依次补充业务层、视图层的文件代码即可。至此,运行并调试项目代码,以便测试执行结果。

4 小结

Spring MVC设计中实现Io C控制,是通过设计外部容器实现的。在项目开发过程中,依据MVC的结构分别设计和实现视图层、控制层、业务层和数据层。由于控制权的反转,特别设计了Bean容器用于创建数据层和业务层对象并装配成Bean对象。将装配好的组件对象返回到控制层,就可以直接调用业务层中的方法完成登录、注册等用户需求了。在这个过程中,紧密围绕配置文件进行合理设计,以便形成完整、协调的处理模型,保证架构运行流畅和无误。

参考文献

[1]林建素,孟康健.Eclipse开发学习笔记[M].北京:电子工业出版社,2008.308-317.

[2]Rod Johnson.Spring framework2.5介绍(下)[J].程序员,2008,(4):104-105.

[3][5]刘斌.大型门户网站是这样炼成的[M].北京:电子工业出版社,2010.353-366.

IOC模式 第4篇

一、W e b的4层模型应用

典型的WEB应用可以为4层, 分别为表现层、持久层、业务层和领域模型层, 每层之间都以一种松散耦合的方式沟通, 与底层的实现技术无关。每层都有独立的功能, 不应和其他层相混淆。每一层之间相互独立, 但需要在他们之间放置通讯接口, 使各层之间可以相互通讯。

1. 表现层

主要实现以下功能:

(1) 负责管理用户请求和响应;

(2) 提供一个控制器代理调用业务逻辑和其它上层处理;

(3) 处理从其它层掷出的异常;

(4) 为显示提供一个模型;

(5) 执行用户接口验证。

2. 持久层

主要实现以下功能逻辑:

(1) 查询相关的信息成为对象;

(2) 保存、更新、删除储存在数据库中的信息。

3. 业务层

主要实现以下功能:

(1) 处理应用程序的业务逻辑和业务验证;

(2) 事务管理;

(3) 保留和其它层交互的接口;

(4) 管理业务层对象之间的依赖;

(5) 增加在表现层和持久层之间的灵活性, 使它们不直接通讯;

(6) 负责控制整个SSH架构的工作流程。

4. 领域模型层

完成实际需求到Java对象的映射, 提供DTO (Data Transfer Object) , 在各层之间传递数据, 优化远程调用性能。滞后时间 (描述了数据的首字节到达目的地之前所经过的时间) 和吞吐量 (描述了在某个时间段 (例如1秒) 内通过网络发送的数据字节数) 是影响网络性能的两个重要因素。吞吐量可以通过提高网络速度来得到改善, 但对滞后时间改善不明显。而要减少滞后时间, 就要考虑减少远程调用次数, 增加每次远程调用的信息传输量, 这就需要一个DTO对象, 在客户端和服务器之间传输信息。但大量的数据传输会占用大量的时间, 这就要在访问次数和每次信息传输量之间有一个权衡。DTO实现有两种形式, 一种是应用现有的集合类型, 另一种是自定义类型, 实际应用中, 一般是结合二者的优点, 采用代码生成技术或提供更强大的集合。

二、S S H构架设计

WEB应用4层模型对应到SSH框架中, 表现层采用Struts框架, 业务层由Spring实现, 持久层由Hibernate实现, 业务逻辑由Logic接口实现, 数据访问逻辑由DAO接口实现。整个应用程序构架分成两部分, 一部分是结构部分 (Architecture Part) , 它是整个程序的骨架, 再一部分是功能 (Function Part) 部分, 两个部分相互分离 (解耦) , 实现了应用程序的“可拆装性”。只要实现了相应接口, 功能部分就可以方便地进行拆装, 只需要在Spring的配置文件中更改配置就可以了。Logic接口采用Field-Oriented设计模式, 即面向不同的行业应用, 设计不同的Logic接口。由于同一行业应用大同小异, 基本业务流程相差不大, 只是处理细节上的差异, 所以这模式大大增加了构架的可重用性。DAO接口采用Fundamental-Oriented设计模式, 即不论对于什么应用, 均只针对数据的CRUD (新建、读取、更新和删除) 设计基本功能。复杂的功能则放在Logic层中由其调用基本的CRUD来实现, 这样做既增加了DAO通用性, 又可以借助Spring的DAO自动生成功能, 自动生成DAO层代码, 既准确又省力。

在Logic层需要进行Action Form和POJO的相互转换, 主要目的是隔离表现层与DAO层, 更好地实现二者的分离, 如果这些转换代码散落到Logic的各处, 则会给修改带来巨大麻烦, 在此将该转换功能抽象出来, 封装成一个 (Transfer) 类, 放在独立的 (common) 包中。如需要修改, 可只针对这个类 (Transfer) 进行, 大大减小了修改的复杂性。

Io C主要是通过DI (Dependency Injection) 技术实现的, 所谓DI就是将实现类注入到Spring中, 由Spring进行统一管理和控制, 并在适当的时候, 对其进行实例化, 并指派给相应的类。在Spring配置文件中, 首先应该配置数据源 (Data Source) , 这是Spring与Hibernate联系的纽带, 接着就是配置Session Factory, 通过它Spring将Data Source纳入自己的管理之下。再下面就是配置自己写的类, 第一个应当是DAO实现类, DAO主要是通过Session Factory操作数据库中的数据, Spring主要是通过Application Context获得DAO, 如下代码所示:

第二个就是Logic实现类, Logic主要是调用DAO提供的功能, 完成用户所要求的操作, 并把操作结果返回给表现层。由于Logic要用到DAO接口和转换接口 (实现Form和POJO的相互转换) , 所以必须提供一定的注入机制, 此处采用Get/Set机制, 相应Logic实现类及配置文件代码片段如下:

其中, <ref/>中bean指向的是注入到Spring的DAO实现类, 它的注入与Logic实现类注入一样, 就不再重复它的实现代码。这里需要说明的是, <ref/>中bean的内容必须与DAO注入中的bean id属性相同, 且Logic bean的<property/>name属性值必须与其实现类中的SET属性一致。

第三个就是配置Action实现类, 它的配置有点复杂。下面就分几步介绍它的配置。第一步, 就是要在Struts的配置文件 (struts-config.xml) 中, 以plug-in的方式导入Context Loader Plug In, 代码如下:

这一步目的是让Struts知道Spring的存在。第二步就是要把Struts配置文件中的action的type属性值由“com.phoenix.struts.action.User Action”改为“org.springframework.web.struts.Delegating Action Proxy”, 即将Struts的action改为Spring的action代理, 目的是将Struts纳入Spring的管理。第三步就是要让Spring知道如何找到Struts的action, 也就是action的注入, 在Spring的配置文件application Context.xml文件中, 加入如下代码:

这里需要说明的是, bean的name属性值必须与Struts配置中action的path属性一致, 且在此用到了Logic接口, 同样也要在实现类中添加注入机制, 与Logic注入DAO机制一样, 不再赘述。

SSH结构中经常出现这样的问题:“Servlet action is not available”, 原因一般有三点:第一, 就是缺少相应的jar包, 解决办法就是, 看一看SSH集成中应该导入哪些jar包并将之导入;第二, DAO类实现不正确, Spring不能正确实例化DAO类。解决方案就是使用Spring自己生成的DAO, 再根据自己的需求进行修改和添加接口;第三, Spring实例化Bean时出错, 这一点涉及相当宽泛, 提供给Spring的任何一个Class都可能引发该问题, 相应办法就是保证Class能被Spring正确实例化。

参考文献

[1]计磊, 李里, 周伟.精通J2EE-EclipseStrutsHi-bernateSpring整合应用案例[M].北京:人民邮电出版社, 2006, 8

上一篇:识别理论下一篇:材料措施论文