13161216443

您所在位置: 首頁> IT培訓> 我理解的IOC技術在Java和C#中比較分析

我理解的IOC技術在Java和C#中比較分析

發布百知教育 來源:IT培訓 2019-12-09

IOC,英文全稱Inversion of Control,中文直譯控制反轉,一般我們稱之為“依賴注入”原則,在我還未過多涉足java領域時,在C#語言24個設計模式中(參見《大話設計模式》)有一個依賴倒轉原則,作為一個設計模式的原則而不是一個模式。在接觸java之后,尤其是spring框架后,被稱之為“依賴注入”IOC設計模式。其實大體的意思和意義都是差不多的,只是在我看來,在C#領域對這個技術的應用沒有那么廣泛,限于.NET技術的先天性,我很少看到這方面的巨作,也許是我太膚淺。在我上次寫基于.NET的MVC ProDinner系列文章時候,查找這方面的文章,幾乎是為零,只能自己去看MVC源碼或者Castle 項目源碼。


首先看看《大話設計模式》中基于C#語言如何詮釋這門藝術的。原著由維修計算機入題,在我們日常生活中,我們很自然地,提高計算機速度需要更高的CPU,需要更快的系統響應度就需要更好的內存,需要更大的存儲介質,就需要擴大硬盤,在這一系列的活動中,于是我們就自然而然的發現,計算機速度依賴CPU,在CPU的使用中我們從來不關心CPU是怎么設計出來的,我們只需要關注這是Intel還是AMD的CPU,因為他決定了你的主板類型,當確定了CPU之后,我們只需關注你需要使用那款CPU,因為接口主板都是一樣的,也即是說,大的功能不會去關注具體每一款產品的實現,而只需要關注產品與產品之間的標準化接口。由此引出來這個原則的定義:


A、高層模塊不應該依賴低層模塊,兩個都應該依賴抽象


B、抽象不應該依賴細節,細節應該依賴抽象


這么講其實是比較抽象的,具體到代碼中實際上就是,層于層之間,各模塊間,各項目間都應該使用接口層來完成模塊的融合。 當某個角色(可能是一個對象實例,調用者)需要另一個角色(另一個對象實例,被調用者)的協助時,在傳統的程序設計過程中,通常由調用者來創建被調用者的實例。而控制反轉中創建被調用者的工作不再由調用者來完成。創建被調用者 實例的工作通常由特定的容器來完成,然后注入調用者,因此也稱為依賴注入。


廢話不多說,理論講得再精彩最終看代碼實現,依據我對這些該概念的理解,我們一起看基于C#語言寫出的實例:


需求場景:


父親在完成一件事情的時候,由于各方面原因需要自己的子女幫忙才能完成,所以,父親需要去調動自己的兒子或者女兒才能完成這件事情


類型設計:


接口 Iperson為被調用者的基類型


類 Father 調用者


類 Son 被調用者


類 Daughter 被調用者


類 Container 依賴注入容器


java培訓班



程序分析:


Father類通過調用抽象層接口,來完成這個操作,至于調用兒子還是女兒我們在構造函數中完成類型的選擇。也就是說Father是調用者,Son和Daughter是被調用者,Container是依賴注入的生成容器。負責將調用者Son或者Daughter對象實例化給調用者。


.NET 程序目錄結構:


java培訓班


打開visual studio 建立控制臺應用程序,接口層代碼實現:

     
      {
         ;
     }


調用者代碼實現:

      
       {
          Iperson iperson;
  
          Container container =  Container();
  
          {
             iperson = container.GetApplication(typeName);
         }
         {
             iperson.operation();
         }
     }


Container 在這里我直接new出實例了,看到這個代碼熟悉java spring框架的同學就似曾相識了,一般是用@autowired來修飾依賴注入的操作句柄。Father類中的operation方法并沒有自己去實現任何操作,而是調用了iperson的操作來實現自己的方法,而iperson只是一個接口類型,需要具體的實現類,代碼才能運行起來,我們看iperson的兩個實現層:

    
      :
    {
        {
            Console.WriteLine();
        }
    }

    
      :
    {
        {
            Console.WriteLine();
        }
    }

Conatiner是實現容器,原理其實很簡單,反射技術,反射原理進行不同的封裝其實就形成了不同的技術框架,java spring的ioc核心離不開反射,許多的數據庫mapper框架同樣也離不開反射,看看代碼實現:

    
     {

        {
           (Iperson) Activator.CreateInstance(Type.GetType(typeName));
        }
    }

當然,我這是最基本的反射實現了,在生成化產品化的框架中反射遠沒有這么簡單,但原理都是相同的。好,看下測試類實現代碼:

     
    {
        {
            
            Father fa =  Father();
            fa.operation();

            
            fa =  Father();
            fa.operation();
        }
    }

程序運行結果:

java培訓班


代碼寫到這里對這個概念有所掌握的同學,其實會是有共鳴的,這是依賴注入最基本的實現了,日常項目開發中基于框架級別來實現這種模式思想,我們很多時候是用修飾符或者配置文件,典型的就是java下面的spring的實現。java spring框架可沒那么簡單,spring兩大核心ioc和aop,實現的手段無非也是如此,但不同的是思想!思想!我這里如若再用java套spring框架來做示例實現java下的IOC的思想,肯定也就沒人有興趣繼續看下去了,這篇文章的含金量就沒那么誘人啦,那么我們來高級點的:

基于java代碼的模擬spring框架IOC實現

實現java下的ioc毫無疑問,我們首先專業術語就換成了,我們需要JavaBean來實現注入,需要factory來實現容器,實現步奏:

1、建立需要實現注入的JavaBean,注入類Person和容器類Persons

2、建立類似spring框架的application.xml配置文件,將依賴的JavaBean和相應注入的屬性配置在xml文件中,我們這里取名叫 IocApplication.xml

3、實現注入容器的factory類,主要負責讀配置文件->依據配置文件進行對象實例化->放入persons map集合當中,以備調用。

java程序目錄結構:


java培訓班


大體實現思路如上所述,好,廢話不多說,看看代碼如何實現,第一步和第二步代碼如下(切換到eclipse下,建立java應用程序):

 com.ioc.bean;


 {

     String name;
    {
         .name;
    }

    {
        .name = name;
    }

}
 com.ioc.bean;


 {

     Person son;
    {
         .son;
    }

    {
        .son = son;
    }

     Person daughter;
    {
         .daughter;
    }

    {
        .daughter = daughter;
    }
}

實現的容器factory代碼量比較大,這里就不依依貼出,所有的源代碼都在附件中可自由下載,這里主要分析幾個關鍵步奏:

實現容器,主要負責一件事件,通過配置的xml,對相應的javabean進行反射,生成實例化對象,存入map中,xml配置實現:

  
  
      
          
            mark  
            
      
      
          
            cindy

容器實現map操作代碼:

    private <,> beanMap= HashMap<,>();

      
    public  init( xmlUrl){
        SAXReader  saxReader= SAXReader();
        File file= File(xmlUrl);
        {
            saxReader.addHandler(, BeanHandler());
            saxReader.read(file);
        }
        (DocumentException e){
            System.out.println(e.getMessage());
        }
    }

      
    public  getBean( beanId){
         obj=;
        obj=beanMap.get(beanId);
         obj;

    }

BeanHandler毫無疑問就是具體去操作IocApplication.xml文件的操作類,代碼比較長,可以下載附件源代碼查看。
好,看下測試類代碼:

package com.ioc.test;

 com.ioc.bean.Person;
 com.ioc.factory.BeanFactory;

 {

      void main([] args) {
        

         xmlUrl=;
         factory=new ();
        factory.(xmlUrl);
         me=()factory.getBean();
        .out.(+me.getName());
    }

}

程序運行結果:

java培訓班


java 模擬spring實現,可以參考這篇文章:http://only1.iteye.com/blog/733550

結束語:

這篇文章我們暫且不來比較依賴注入和反轉的區別,依賴反轉和依賴注入很多程序員把這兩個概念當成一個理解,認為只是不同的解釋,其實細分還是有區別的
1、依賴注入是從應用程序的角度在描述,也就是說,應用程序依賴容器創建并注入它所需要的外部資源;而控制反轉是從容器的角度在描述,容器控制應用程序,由容器反向的向應用程序注入應用程序所需要的外部資源。

2、IOC,控制反轉是軟件運行時體現出來的一個特征:如果對象A運行時依賴于對象B,但A并不去創建B,而是從外界直接取得B。也就是說,一個對象并不是自己去創建它所依賴的其它對象。DI,依賴注入是控制反轉的一種實現手段。如上面的例子,B的取得并不需要A的干涉,而是利用某些框架在通過構造參數或屬性設置來實現。

關于這些這里就不展開敘述,后面我們再詳細討論,這節主要討論依賴注入,我們首先在這節暫時認為這是一個相同的概念。作為概述,首先我們了解下IOC概念,再看看java和C#在這一概念上的運用比較。


java培訓班:http://www.onhairsalon.com/java2019


上一篇:python培訓班 | NumPy 字符串操作

下一篇:應屆生去公司找個Java程序員的職位需要什么技能?

相關推薦

www.onhairsalon.com

有位老師想和您聊一聊

關閉

立即申請