`
825197453
  • 浏览: 101756 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

控制反转

阅读更多
【经典导读】 IOC: 一种让服务消费者不直接依赖于服务提供者一 种组件设计方式,一种减少类与类之间依赖的设计原则,一种使服务与服务提供者完全分开的设计原则。

【原文】

控制反转(Ioc)的设计原则
                                                                         --减轻组件间的依赖性及藕合性的设计原则
                                           

导读

1.缘由

2、回顾面向对象思想

3.什么是Ioc

4、现行的几种实现方式

5.结论

6.附录


一、缘由
“万事万物皆有姻缘”,这一句话本是佛家偕语。不过笔者认为,这一句话也真是道出了世间万事万物的相辅相成的最彻底的一句解释。在IT这一行,更新换代比光速还快,我想同仁们都不会反驳我这句话吧!要不试试,从艺术性的工作, 到工程化的项目,从面向过程到面向对象,从面向对象到面向方面!每一种思想都是那么的伟大,每一种思想都没有任何一个人(还真是任何一个人,不信的话,你 找几个大师级的人物问问,他们对哪一种思想完全理解并应用了?)完全理解并应用他,但新的思想又出来了(这种思想说的是软件类的思想,编程的思想,当然没 有孔子孟子之类说)!好像说了这么多,跟“万事万物皆有姻缘”没有任何关系一样,有,当然有,虽然这么多的思想没有任何一个人完全贯通使用,但提出一种新 的思想来使用,这是事物发展的需要,也是必然的趋势,艺术性的编程不能实用于大型应用,因此提出工程化,面向过程使软件升级特别困难,因此懒惰的人们提出 了面向对象的复用思想
,但面向对象的思想还是复杂,懒惰的人们就想要做更少的工作,因此提出了面向方面!“万事万物皆有姻缘”因为人们的懒惰,所以该放下的就放下了,重新拿起新的事物!那么为什么现在在编程界又提出了控制反转(Ioc)呢?下面我们看一个经常引用的例子:
public Class MyClass{
    Logger _logger=Logger.getLogger(this.getClass());//实例化_logger   
    public void helloWorld(String){
       _logger.DEBUG("Start print .....");
       System.out.println("Hello! The world!");
       _logger.DEBUG("End print.......");
    }    
}

现在想,如果我实例化_logger的方式变了,变成了:
Logger _logger=Logger.getLogger("My Class DEBUG");
你们想想是不是应该要改上面这个已经实现了的CLASS呢?结果是肯定的,如果我有10个类,100个,那是不是要改10次,100次,我们称这样的软件开发为藕合性太强或依赖太深!
“万事万物皆有姻缘”,控制反转(Ioc)就是为了解决这样的问题而提出的原则!
二、面向对象思想回顾
首先我们回顾面向对象思想的一些内容,笔者在《软件工程之 面向对象软件工程基础(软件工程实践之三)》一文中概术面向对象时,面向对象=类+对象+继承+通信,面向对象就是这样的一种思想。将组件分类,使用时再 实例化,类与类之间可以继承,他们通过通信联系。在这里我们要重新到一个概念是服务,在很多面向对象文章中都提到了服务,那么什么是服务呢?即一个类向另 一个类提供他想要的接口(或方法)。
如下例:
public ClassA{
   /*
    *下面是ClassA提供给其它类使用的接口
    */
   public void bussiness(){
      System.out.println("execute bussiness");
   }
}

public ClassB{
   ClassA classA=new ClassA();//classA即将向ClassB提供服务
   public executebussiness(){
     classA.bussiness();//调用了ClassA的bussiness方法来得到服务
   }
}
另 两个概念就是服务提供者与服务使用者,从上例可以看出,ClassA就是服务提供者-提供业务服务的一方 ,ClassB就服务使用者(也称消费者)-使用业务服务的一方,在他们之间采用的联系的方式我们叫做通信。   从上面的例子可以看出,服务提供者提供服务给消费者是特别直接的。这样有如下坏处:
   如果服务提供者变了呢?这样是不是需要改动每个服务消费者?   这样的一种依赖关系?我们用什么来解决呢?Ioc,控制反转,它让服务消费者不直接依赖于服务提供者!
三、什么是控制反转(Ioc)?
    一种让服务消费者不直接依赖于服务提供者一 种组件设计方式,一种减少类与类之间依赖的设计原则,一种使服务与服务提供者完全分开的设计原则。我们将第一个例子改进一下:
    public Class MyClass{
       Logger _logger;
       public void setLogger(Logger logger){
          this._logger=logger;
       }
       public void helloWorld(){
          _logger.DEBUG("Start DEBUG print....");
          System.out.println(“hello world");
          _logger.DEBUG("End DEBUG print.....");
       }
   }
  
现在调用时:
public Class UseLogger{
   Logger _logger=Logger.getLogger(this.getClass());
   public void execute(){
     MyClass myClass=new MyClass();
     myClass.setLogger(_logger);
     myClass.helloWorld();
}
}
这 样,我们发现,整个使用Logger的控制权全部在客户端,即Logger给MyClass提供的服务的方式已经提交给了最终客房,完全取决于客户端的需 要,而不是在MyClass调用服务时就依赖于Logger了,这样,服务提供者(Logger)与消费者(MyClass)之间的依赖就少了很多。这就 是Ioc的一种具体实现方式。
   我们可以看出来,Ioc更通俗的一种解释就是:我在需要服务时,才告诉你怎么去给我提供服务_logger的定义在MyClass中只是一个预留的定义,直到UseLogger最终消费时才将具体怎么使用Logger通知给MyClass.

四、控制反转的几种设计方式?
目前控制反转的几种实现方式:
   .基于方法的(Method-based Ioc,Type-0)
   .基于接口的(Interface-based Ioc,Type-1)
   .基于设值的(Setter-based Ioc,Type-2)
   .基于构造的(Construtor-based Ioc,Type-3)
.Type-0
基于方法的实现,主要依赖的是接口,,服务提供者将自己的接品传递给消费者方法,而不是将具体的实现类型传递过去,如下:
public interface MyClass{
   public void helloWorld(Logger _logger);
}
调用时:
Logger _logger=Logger.getLogger(this.getClass());
MyClass myClass=new MyClassImpl();
myClass.helloWorld(_logger);
从上面可以看出,这样Logger与MyClass的具体服务都依赖于接口MyClass,Logger提供服务时也止于方法上,Logger服务提供与
MyClassImpl消费之间隔开了,
.Type-1
基于接口的实现,主要是采用容器来管理服务提供者,消费者只要实现服务提供者的接口就可以达到服务的目的了。
如下:
Public Class MyClassImpl implements MyClass,Logger {
protected Logger _logger;
/*
   *实现Logger的enableLogger有效方法
   */
   public void enableLogger(Logger logger){
     _logger=logger;
}
public void helloWorld(){
   _logger.DEBUG("ENABLE");
}
}
怎么调用 :
MyClass myClass=new MyClass();
Logger _logger=Logger.getLogger(this.getClass());
Container.enableLogger(myClass,_logger);
myClass.helloWorld();
可 以看出,这样的实现,必须要有珍上容器来检查是否实现了Logger接品,如果实现凶才能有效,否则就没有作用。这样的方法大大的减少了类与类之间的依 赖.但必须要实现一个容器。而且发现,每一个实现的类都直接跟服务提供者(本例就是Logger)的接口有了很直接的联系。
.Type-2
     的方式,就是通过BEAN的setter方法来给成员变量赋值,我们采用这种方式,就可以通过一个配置文件,配置好相应的Bean,然后通过一个容器来得到这个服务Bean,这样组件之间的依赖就已经少了。
如:
public Class MyClass{
private Logger logger;
public void setLogger(Logger logger){
    this.logger=logger;
}
public void helloWorld(){
   logger.DEBUG("ENABLE");
}
}
如Spring采用的方式就是如此,它的全过程如下:
配置文件:
<Beans>
<Bean id="logger" Class="Logger"/>
<Bean id="myClass" Class=MyClass">
    <property name="logger"><ref bean="logger"/></property>
</Bean>
</Beans>
调用:
InputStream is=Client.class.getClassLoader().getResourceAsStream("bean.xml");
BeanFactory beans=new XMLBeanFacotory(is);
MyClass myClass=(MyClass)beans.getBean("myClass");
myClass.helloWorld();
从上面可以看出,所有的服务提供类及消费类都已经通过一个容器类来提取配置文件统一管理了。

.Type-3
基于构造的Ioc,顾名思义,就是通过构造子来传递服务提供者的具体实例来实例化服务接口。
如下:
public Class MyClass{
private Logger _logger;
public MyClass(Logger logger){
    _logger=logger;
}
public void helloWorld(){
    _logger.DEBUG("ENABLE");
}
}
这样,注册服务组件时在构造方法处完成,但,这样一来继承和构造时都有一定的困难。
五、结语
        Ioc的一个真正的目的就是移植,减少组件的依赖性!但我们通过上面的例子,有没有发现,这中间的依赖还很大呢?比如:如果我要将Logger类移植使用另外一个公司的产品的时候,这个时候,要移植的量是不是还很大呢?
六、附录
1、术语
控制反转(Ioc-Inversion Of Control);
容器(container),用于组件创建,生存的环境;
框架(framework::一组用于对特定领域构造的可复用的基础组件

分享到:
评论

相关推荐

    c# 依赖注入 控制反转

    ### C# 依赖注入 控制反转 #### 一、IoC(控制反转)简介 IoC,即"Inversion of Control"(控制反转),是软件工程领域的一个重要概念,特别是面向对象编程中的一个关键设计原则。从字面上理解,IoC指的是程序运行...

    体验控制反转的理念及Spring介绍技术文档

    ### 体验控制反转的理念及Spring框架介绍 #### 1. Spring 框架概述 Spring框架自2002年由Rod Johnson在其著作《Expert One-on-One J2EE Design and Development》中提出以来,逐渐成为了企业级Java应用开发中最受...

    spring 控制反转的模拟程序

    Spring框架是Java开发中最常用的轻量级框架之一,它的核心特性是依赖注入(Dependency Injection,简称DI),也常被称为控制反转(Inversion of Control,简称IoC)。控制反转是一种设计模式,它改变了传统应用程序...

    控制反转应用,模拟Hibernate

    在编程领域,控制反转(Inversion of Control,简称IoC)是一种设计模式,它将对象的创建和管理责任从应用程序转移到框架或容器中。在Java编程中,IoC通过依赖注入(Dependency Injection,DI)来实现,使得组件之间...

    Spring IOC 控制反转

    ### Spring IOC控制反转详解 #### 一、Spring框架简介 Spring框架是一个开源的Java平台,提供了全面的基础架构支持,让开发者能够轻松地开发出松耦合的应用程序。它通过依赖注入(Dependency Injection, DI)和...

    spring技术--IOC控制反转课件.ppt

    **Spring技术--IOC控制反转** 在Java开发领域,Spring框架以其强大的功能和广泛的应用而闻名。其中,IOC(Inversion of Control,控制反转)是Spring的核心特性之一,它改变了传统对象创建和管理的方式,实现了依赖...

    spring 控制反转和依赖注入.docx

    Spring 控制反转和依赖注入基础知识详解 Spring 框架是 Java 企业级开发的轻量级开发框架,于 2003 年创建,主要用于解决企业级开发的复杂性。其主要优势在于分层架构,允许在不同层级中使用一个组件(其他框架)...

    控制反转和容器(二)

    **控制反转(IoC)与容器** 控制反转(Inversion of Control,简称IoC)是一种设计模式,它在软件工程中被广泛应用于构建可扩展、松耦合的系统。这个概念的核心是将对象的创建和依赖关系的管理从应用程序代码中剥离...

    Ioc(控制反转)的例子

    "IoC(控制反转)"是软件设计模式中的一个重要概念,它在现代软件开发,特别是.NET框架下的C#编程中占据了核心地位。控制反转的主要思想是将对象之间的依赖关系从代码内部转移到外部容器,从而使代码更加灵活、可...

    IOC控制反转在代码中体现.

    ### IOC控制反转在代码中的体现 #### 一、IOC(Inversion of Control)概念解析 IOC,即控制反转,是一种设计思想,在Java开发领域中,它主要被用来消除程序之间的依赖性,使得类的设计更加灵活。传统的编程模式下...

    asp.net mvc4控制反转

    **ASP.NET MVC4 控制反转 (IoC) 知识详解** 在ASP.NET MVC4框架中,控制反转(Inversion of Control,简称IoC)是一种设计原则,它改变了传统程序设计中对象之间的依赖关系,使得应用程序的组件可以更加灵活、可...

    helloIoc.zip spring ioc控制反转简单测试代码

    Spring框架的核心特性之一就是依赖注入(Dependency Injection,简称DI),它通过控制反转(Inversion of Control,简称IOC)实现。这个"helloIoc.zip"压缩包包含的是一组用于演示Spring IOC基本概念和使用的测试...

    Spring 控制反转 依赖注入

    **Spring 框架中的控制反转 (IoC) 和依赖注入 (DI)** 在软件开发中,控制反转(Inversion of Control,简称IoC)是一种设计原则,它将对象的创建和管理权从代码中剥离出来,转交给一个外部容器(如Spring框架)。...

    Spring_01_入门篇_依赖注入(控制反转)_XML

    它的核心特性是依赖注入(Dependency Injection,简称DI),也被称为控制反转(Inversion of Control,简称IOC)。这个特性使得开发者可以更专注于业务逻辑,而不需要过多地关注对象的创建和管理。 **依赖注入(DI...

    学习Spring笔记_IoC(控制反转)简介

    **Spring框架中的IoC(控制反转)概念** 在软件开发中,IoC(Inversion of Control,控制反转)是一种设计模式,它将对象的创建和管理责任从代码中剥离出来,交由一个容器来处理。Spring框架是Java平台上的一个核心...

    springIOC控制反转 依赖注入实例

    Spring IOC(Inversion of Control,控制反转)是Spring框架的核心特性,它改变了传统Java应用程序中对象的创建和管理方式。在传统的程序设计中,我们通常手动创建对象并管理它们之间的依赖关系,而在Spring中,这些...

    Spring_01_入门篇_依赖注入(控制反转)_ANN

    Spring的核心特性之一是依赖注入(Dependency Injection,简称DI),也称为控制反转(Inversion of Control,简称IoC)。 **依赖注入 (DI) 和 控制反转 (IoC)** 依赖注入是Spring的核心设计原则之一。它是一种设计...

    Spring.NET控制反转(IoC)和面向切面(AOP)的容器框架

    Spring.NET 控制反转(Inversion of Control,英文缩写为IoC),也叫依赖注入(Dependency Injection)。我个人认为控制反转的意思是依赖对象(控制权)发生转变,由最初的类本身来管理依赖对象转变为IoC框架来管理...

    webwork 控制反转小例子,配置文件的写法

    WebWork是一个古老的Java Web应用程序框架,它在早期的开发中引入了控制反转(IoC,Inversion of Control)的概念,这种设计模式对于提高代码的可维护性和灵活性具有重要作用。在这个小例子中,我们将探讨WebWork...

    控制反转_百度百科1

    控制反转_Inversion of Control(IoC) 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。控制反转一般分为两种类型,...

Global site tag (gtag.js) - Google Analytics