分离关注( Separation of Concerns : SOC)是Ioc模式和AOP产生最原始动力,通过功能分解可得到关注点,这些关注可以是 组件Components, 方面Aspects或服务Services。

  从GoF设计模式中,我们已经习惯一种思维编程方式:Interface Driven Design 接口驱动,接口驱动有很多好处,可以提供不同灵活的子类实现,增加代码稳定和健壮性等等,但是接口一定是需要实现的,也就是如下语句迟早要执行:

  AInterface a = new AInterfaceImp();

  AInterfaceImp是接口AInterface的一个子类,Ioc模式可以延缓接口的实现,根据需要实现,有个比喻:接口如同空的模型套,在必要时,需要向模型套注射石膏,这样才能成为一个模型实体,因此,我们将人为控制接口的实现成为“注射”。

  Ioc英文为 Inversion of Control,即反转模式,这里有著名的好莱坞理论:你呆着别动,到时我会找你。后被Martin Fowler改名为 Dependency Injection 依赖注射,也就是将类之间的关系通过第三方进行注射,不需要类自己去解决调用关系。

  其实Ioc模式也是解决调用者和被调用者之间的一种关系,上述AInterface实现语句表明当前是在调用被调用者AInterfaceImp,由于被调用者名称写入了调用者的代码中,这产生了一个接口实现的原罪:彼此联系,调用者和被调用者有紧密联系,在UML中是用依赖 Dependency 表示。

  但是这种依赖在分离关注的思维下是不可忍耐的,必须切割,实现调用者和被调用者解耦,新的Ioc模式 Dependency Injection 模式由此产生了, Dependency Injection模式是依赖注射的意思,也就是将依赖先剥离,然后在适当时候再注射进入。

Ioc模式(Dependency Injection模式)有三种:

第一种类型 从JNDI或ServiceManager等获得被调用者,这里类似ServiceLocator模式。 1. EJB/J2EE
2. Avalon(Apache的一个复杂使用不多的项目)
第二种类型 使用JavaBeans的setter方法 1. Spring Framework,
2. WebWork/XWork
第三种类型 在构造方法中实现依赖 1. PicoContainer,
2. HiveMind

  有过EJB开发经验的人都知道,每个EJB的调用都需要通过JNDI寻找到工厂性质的Home接口,在我的教程EJB是什么章节中,我也是从依赖和工厂模式角度来阐述EJB的使用。

  在通常传统情况下,为了实现调用者和被调用者解耦,分离,一般是通过工厂模式实现的,下面将通过比较工厂模式和Ioc模式不同,加深理解Ioc模式。

工厂模式和Ioc

  假设有两个类B 和 C:B作为调用者,C是被调用者,在B代码中存在对C的调用:

public class B{
   private C comp; 
  ......
}

  实现comp实例有两种途径:单态工厂模式和Ioc。

工厂模式实现如下:

public class B{
   private C comp; 
  private final static MyFactory myFactory = MyFactory.getInstance();

  public B(){
    this.comp = myFactory.createInstanceOfC();

  }
   public void someMethod(){
    this.comp.sayHello();
  } 
  ......
}

特点:

  • 每次运行时,MyFactory可根据配置文件XML中定义的C子类实现,通过createInstanceOfC()生成C的具体实例。

使用Ioc依赖性注射( Dependency Injection )实现Picocontainer如下,B类如同通常POJO类,如下:

public class B{
   private C comp; 
  public B(C comp){
    this.comp = comp;
   }
   public void someMethod(){
    this.comp.sayHello();
   }
  ......
}

假设C接口/类有有一个具体实现CImp类。当客户端调用B时,使用下列代码:

public class client{
   public static void main( String[] args ) {
    DefaultPicoContainer container = new DefaultPicoContainer();
    container.registerComponentImplementation(CImp.class);
    container.registerComponentImplementation(B.class);
    B b = (B) container.getComponentInstance(B.class);
    b.someMethod();
   }
}

  因此,当客户端调用B时,分别使用工厂模式和Ioc有不同的特点和区别:

  主要区别体现在B类的代码,如果使用Ioc,在B类代码中将不需要嵌入任何工厂模式等的代码,因为这些工厂模式其实还是与C有些间接的联系,这样,使用Ioc彻底解耦了B和C之间的联系。

  使用Ioc带来的代价是:需要在客户端或其它某处进行B和C之间联系的组装。

  所以,Ioc并没有消除B和C之间这样的联系,只是转移了这种联系。
  这种联系转移实际也是一种分离关注,它的影响巨大,它提供了AOP实现的可能。

Ioc和AOP

  AOP我们已经知道是一种面向切面的编程方式,由于Ioc解放自由了B类,而且可以向B类实现注射C类具体实现,如果把B类想像成运行时的横向动作,无疑注入C类子类就是AOP中的一种Advice,如下图:

  通过下列代码说明如何使用Picocontainer实现AOP,该例程主要实现是记录logger功能,通过Picocontainer可以使用简单一行,使所有的应用类的记录功能激活。

首先编制一个记录接口:

public interface Logging {

  public void enableLogging(Log log);

}

有一个LogSwitcher类,主要用来激活具体应用中的记录功能:

import org.apache.commons.logging.Log;
public class LogSwitcher
{
  protected Log m_log;
  public void enableLogging(Log log) {
    m_log = log;
    m_log.info("Logging Enabled");
  }
}

一般的普通应用JavaBeans都可以继承这个类,假设PicoUserManager是一个用户管理类,代码如下:

public class PicoUserManager extends LogSwitcher
{

  ..... //用户管理功能
}
public class PicoXXXX1Manager extends LogSwitcher
{

  ..... //业务功能
}
public class PicoXXXX2Manager extends LogSwitcher
{

  ..... //业务功能
}

注意LogSwitcher中Log实例是由外界赋予的,也就是说即将被外界注射进入,下面看看使用Picocontainer是如何注射Log的具体实例的。

DefaultPicoContainer container = new DefaultPicoContainer();
container.registerComponentImplementation(PicoUserManager.class);
container.registerComponentImplementation(PicoXXXX1Manager.class); 
container.registerComponentImplementation(PicoXXXX2Manager.class);
.....

Logging logging = (Logging) container.getComponentMulticaster();

logging.enableLogging(new SimpleLog("pico"));//激活log

  由上代码可见,通过使用简单一行logging.enableLogging()方法使所有的应用类的记录功能激活。这是不是类似AOP的advice实现?

  总之,使用Ioc模式,可以不管将来具体实现,完全在一个抽象层次进行描述和技术架构,因此,Ioc模式可以为容器、框架之类的软件实现提供了具体的实现手段,属于架构技术中一种重要的模式应用。J道的Jdon框架使用了Ioc模式,JiveJdon3.0是一个IOC/DI成熟应用。

转载于:https://www.cnblogs.com/Johnfx-home/p/4113237.html

Ioc模式(又称DI:Dependency Injection 依赖注射)相关推荐

  1. 再谈angularjs DI(Dependency Injection)

    在前面已经介绍了关于angularjs,以及扩展了一些jQuery ui的一些组件为angularjs的directive.在这里应进口007 在上篇留言我们来看看在angularjs中的DI特性. ...

  2. Spring IoC容器和Dependency Injection模式

    轻松学习Spring<一> IoC容器和Dependency Injection模式 最近公司需要,项目中要用到Spring和Ibatis.趁着过年好好学习学习.Ibatis就如同Hibe ...

  3. IoC容器和 Dependency Injection模式 Inversion of Control Containers and the Dependency Injection pattern

    原文链接:http://www.martinfowler.com/articles/injection.html 文末有中文翻译版本,martinfowler上有提供中文版的pdf,也可以自行下载 中 ...

  4. 设计模式--谈谈IoC、DI、DIP、IoC Container、控制反转与依赖注入

    1. 介绍 控制反转(IoC).依赖反转原理(DIP).依赖注入(DI)和IoC容器这些术语你都清楚嘛? 2. 概念讲解 2.1. IoC 控制反转(IoC):是一种设计模式,用于在面向对象的设计中反 ...

  5. java 注入依赖_依赖注入(Dependency Injection)

    一.依赖注入的概念了解 介绍依赖注入(di),首先要先了解一个概念--即控制反转(ioc). 控制反转是面向对象编程的一种设计原则,可以用来减低计算机代码之间的耦合度.在传统的应用程序中,都是程序员手 ...

  6. 跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(六)(应用IOC模式)...

    前五篇已经把Models 介绍完啦,从今天开始我们要介绍"V"&"C"啦.现在我们还是从MVC的定义说起,其实MVC最大的好处就是M层(脱离V与C)可以 ...

  7. Martin Fowler关于IOC和DI的文章(中文版) IoC容器和Dependency Injection模式

    摘要:Java社群近来掀起了一阵轻量级容器的热潮,这些容器能够帮助开发者将来自不同项目的组件组装成为一个内聚的应用程序.在它们的背后有着同一个模式,这个模式决定了这些容器进行组件装配的方式.人们用一个 ...

  8. IoC容器和Dependency Injection模式

    注:本文转自http://insights.thoughtworkers.org/injection/,请尊重译者的劳动成果,转载需注明出处. 2017年3月3日 by Martin Fowler L ...

  9. IoC 容器和 Dependency Injection 模式[转]

    转自:插图版<IoC 容器和Dependency Injection 模式> 原文地址:Inversion of Control Containers and the Dependency ...

最新文章

  1. 2019年工信部重点实验室名单公布 涵盖卫星导航及人工智能等多个领域
  2. Ubuntu 下mysql service 启动问题
  3. ie浏览器修复_腾讯安全:IE浏览器曝远程执行代码漏洞 腾讯安全强势推出漏洞修复工具...
  4. c++预处理命令#pragma 用法
  5. Kubernetes 容器编排
  6. 如何修改 pdf 文件默认的显示图标
  7. miller_rabin 模板
  8. 数字三角形——递归、递推、记忆化搜索
  9. 面向中后台复杂场景的低代码实践思路
  10. 每日算法系列【LeetCode 658】找到 K 个最接近的元素
  11. java 开发必备的安全架构知识
  12. git拉取远程仓库命令代码
  13. python中seek方法_python文件操作及seek偏移详解
  14. Power query (Power BI)一步到位傻瓜式合并工作簿,史上最好用
  15. oracle18c打开pdb服务,SQLPLUS 连接 Oracle 18c CDB和PDB方法
  16. JS--实现漂浮广告
  17. Android OpenCV(三十二):霍夫直线检测
  18. [转]微服务与Docker
  19. 行级锁,表级锁,乐观锁,悲观锁简介
  20. 乔治亚理工学院计算机专业,佐治亚理工学院电子与计算机专业

热门文章

  1. Airbnb如何简化1000多位工程师的Kubernetes工作流程?
  2. TextView的跑马灯效果(AS开发实战第二章学习笔记)
  3. 027——VUE中事件修饰符:stop prevent self capture
  4. code第一部分数组:从有序数组中移除重复的数据
  5. 用Java获取vSphere相关数据
  6. 【翻译】如何在Ext JS 6中使用Fashion美化应用程序
  7. Visual Studio 2015 RC中的ASP.NET新特性和问题修正
  8. 无锡给的sql excel转换
  9. 问题 E: 求1+2+...+n=?
  10. python提取数组元素_python简单获取数组元素个数的方法