如果你之前使用过JavaEE开发中的Spring框架的话,那么你一定对依赖注入并不陌生。依赖注入(DI: Dependency Injection)是控制反转(IoC: Inversion of Control)的实现方式之一,另外一种是依赖查找(DL: Dependency Lookup)。当然在Spring框架中主要使用到了控制反转中的依赖注入这种方式。当然在Spring框架中除了依赖注入外,还有一个重要的概念那就是面向切面编程(AOP)。

简单的说,依赖注入负责往类中注入依赖对象,而面向切面编程则负责往里添加代码段的。本篇博客我们主要聊的就是依赖注入,关于AOP和依赖查找的内容,如果以后有机会,会在后边的博客进行介绍。

本篇博客不是使用Java语言实现的,而是使用Objective-C来实现的。实现依赖注入的具体方式就是使用反射机制来实现的,本篇博客,我们就使用OC的反射机制来看一下iOS开发中的依赖注入的实现方式。当然在Java的Spring框架中是在XML文件中配置的JavaBean,入乡随俗,本篇博客我们就使用iOS开发中常用的PList文件来存储类似于JavaBean的东西,也就是数本篇博客我们使用PList文件来代替XML文件。废话少说,进入我们的主题。

一、依赖注入的实现机制

依赖注入,听起来特别高大上,其实真正理解其工作原理后,也没什么东西。本篇博客采用的代码实例与之前我们聊“策略模式”的示例一致。关于之前的策略模式的博客,请移步于《“穿越火线”中的“策略模式”(Strategy Pattern)》。当然我们之前的示例是使用的Swift来实现的,本篇博客使用的是OC, 虽然语言不通,但是思想是一致的。在“策略模式”中我们通过策略模式为不通的军官提供不同的武器策略。而本篇博客,我们依然采用这个思路,不过我们是依照“依赖注入”的方式来为不同的军官提供不同的武器策略。

下方就是我们本篇博客使用示例的类图。WeaponType是所有武器的父类,在其中扮演者“武器接口”的角色。所有的武器都继承自WeaponType。而Character角色类依赖于WeaponType武器接口类,所有Character与WeaponType存在依赖关系。

  

“依赖注入”从字面上看,就是注入依赖。也就是将依赖关系的对象注入到相应的类中。而在上述示例中,Character依赖于WeaponType接口,如果使用“依赖注入”来解决这层依赖关系的话,就是通过反射机制(“Runtime”)动态的将WeaponType的子类的对象注入到Character对应的依赖属性中去。而反射时需要的依赖关系信息,我们就从PList文件中进行读取,当然Java中是从XML中进行配置的,这就是“依赖注入”。

本篇博客我们就来根据上述类图的依赖关系,来完整的实现这个实例。当然在真正实现时,我们用到的主要核心内容是“面向接口编程”、“面向对象的多态性”、“反射机制”、“PList文件的读取与操作”。下方会一一介绍。

二、示例工程的目录结构

接下来我们就来概述一下本篇博客所使用到的实例的工程结构,也就是先整体的了解一下本篇博客所涉及的示例工程。下方这个工程目录结构就是我们本篇博客所涉及的示例的目录结构。Weapon文件夹中存放的就是武器策略所涉及的武器接口与武器类。Character文件夹中存放的就是武器使用者所对应的目录。PList文件则存储的是Character类依赖WeaponType接口的具体类的依赖信息。Relation类则是负责读取PList文件中的依赖信息,根据这些依赖信息将依赖对象通过“反射机制”注入到相应的类中。

  

三、PList文件中的内容

本篇博客中的PList文件的作用就类似于Spring框架中用来配置JavaBean的XML。当然我们本篇博客的PList文件的存储内容的结构与形式与Spring中的XML有所不同,但是其作用都是一样的,都是用来描述类之间的依赖关系的。

下方截图就是本篇示例所涉及的PList文件中的内容。从下方文件中,我们可以看出其中存储了三个类的信息,一个是Lieutenant(中尉)类,一个是Captain(上尉)类,最后一个就是Soldier(士兵)类。每个类也就是Java中常说的JavaBean,Relation类可以根据反射机制根据这些类在PList文件中提供的信息来实例化相应的类的对象。

我们就以Lieutenant为例。在PList文件中,其实Lieutenant就对应这一个类,从Lieutenant对应的信息来看,Lieutenant的对象由Character类实例化,但是在实例化时需要给Character的对象依赖属性weapon赋一个HK48Weapon类的对象。当然这一系列实例化以及赋值的动作都是由反射机制完成。稍后我们会给出具体实现。

  

四、通过PList文件创建类

Relation类就是赋值加载相应的PList文件内容,然后根据其加载的内容利用反射机制生成相应的类的对象。下方代码片段就是Relation类加载上述的PList文件内容,让后给据这些内容生成相应的类的对象的。下方这个代码片段根据Relation提供的上下文分别创建了Lieutenant对象、Captain对象以及Soldier的对象。具体如下所示。

  

根据上下文创建完对象后,都会调用fire方法,因为每个对象对应的上下文不同,也就是注入的依赖对象不同,所以fire方法执行的结果也不同。下方是上述代码的运行结果,如下所示:

  

五、使用反射机制注入依赖对象

接下来我们就要来看一下如何使用反射机制来注入依赖对象的,也就是Relation类的具体实现。

1.通过初始化方法提供plist文件

下方是Relation类的构造器,构造器中有个参数plistFileName, 该参数就是用来存储依赖上下文信息的plist文件。Relation类在实例化对象时,收到该文件后,会加载该文件中的上下文信息,也就是我们plist文件中的内容。具体代码如下所示。

  

下方代码片段就是本篇博客的核心代码,根据PList文件中提供的上下文信息,生成相应的对象,并给对象相应的属性注入依赖对象。当然下方是通过Setter方法来设置依赖对象的。设置完毕后,返回该注入好依赖的对象。具体如下所示。

  

今天博客就先到这儿吧,以后我们找个合适的时间再聊聊依赖查找和面向切面编程的东西。下方的github链接是本篇博客所涉及Demo的源码分享链接,如下所示。

源码的github分享链接:https://github.com/lizelu/DependencyInjectionForiOS

类比Spring框架来实现OC中的依赖注入的更多相关文章

  1. Spring-初识Spring框架-IOC控制反转(DI依赖注入)

    ---恢复内容开始--- IOC :控制反转 (DI:依赖注入)使用ioc模式开发 实体类必须有无参构造方法1.搭建Spring环境下载jarhttp://maven.springframework. ...

  2. JavaEE开发之Spring中的依赖注入与AOP

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  3. JavaEE开发之Spring中的依赖注入与AOP编程

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  4. Spring学习(一)——Spring中的依赖注入简介【转】

      [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...

  5. Spring学习(一)——Spring中的依赖注入简介

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

  6. 三大框架 之 Spring(IOC控制反转、DI依赖注入)

    目录 常用词汇 left join与left outer join的区别 Struts2的标签库导入 Spring Spring概述 什么是Spring spring特点 下载 IOC 什么IOC 传 ...

  7. Spring学习(三)——Spring中的依赖注入的方式

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

  8. C#中的依赖注入那些事儿

    目录 目录 1 IGame游戏公司的故事 1.1 讨论会 1.2 实习生小李的实现方法 1.3 架构师的建议 1.4 小李的小结 2 探究依赖注入 2.1 故事的启迪 2.2 正式定义依赖注入 3 依 ...

  9. React 源码中的依赖注入方法

    一.前言 依赖注入(Dependency Injection)这个概念的兴起已经有很长时间了,把这个概念融入到框架中达到出神入化境地的,非Spring莫属.然而在前端领域,似乎很少会提到这个概念,难道 ...

随机推荐

  1. redis 安装启动及设置密码<windows>

    redis 1. 安装 1.1 下载解压包,直接解压到任意路径下即可 windows下载地址:ttps://github.com/MSOpenTech/redis/releases 2.启动 2.1 ...

  2. JavaScript对象属性的基础教程指南

    JavaScript是使用“对象化编程”的,或者叫“面向对象编程”的.所谓“对象化编程”,意思是把JavaScript能涉及的范围划分成大大小小的对象,对象下面还继续划分对象直至非常详细为止,所有的编 ...

  3. FMS带宽的需求计算法

    在开始一个使用 FLASH MEDIA SERVER的项目开始之前,最好能够对你项目使用FLASH MEDIA SERVER 3的带宽需求进行计算.这样对你的项目最终的实现效果,会有一个稳定的结果:去 ...

  4. JS高级程序设计--笔记

    1.JS分三个部分:ECMAScript.DOM.BOM       1)ECMAScript:提供核心语言功能       2)DOM:提供访问和操作网页内容的方法和接口       3)BOM:提 ...

  5. office如何去除多页签

    写文档会遇到同时打开多个文档,偶尔可能需要对比,而有时office会出现跟浏览器类似的多页签界面.如何去除多页签,office本身没有此加载项,一般都是作为插件或组件形式另外安装,导致我们不知道从哪里 ...

  6. 蓝桥网试题 java 入门训练 序列求和

    ---------------------------------------------------------------------------------------------------- ...

  7. MySQL管理命令

    1.验证MySQL安装 在成功安装Mysql后,一些基础表会表初始化,在服务器启动后,你可以通过简单的测试来验证Mysql是否工作正常. 使用 mysqladmin 工具来获取服务器状态: 使用 my ...

  8. css 样式重置

    html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, ...

  9. Webappbuilder开发快速预览

    Webappbuilder开发快速预览 by 李远祥 Webappbuilder for ArcGIS 是由ArcGIS JavaScripit API和dojo创建的,它允许通过创建自己的widge ...

  10. 解决IIE8不支持媒体查询的方法

    最近在解决UI问题时碰到以下浏览器不兼容性问题(本人属于UI业余操作者,很多想法就很业余了): 问题:IE8及其以下低版本IE浏览器在缩小窗口时,UI没有按照相应的要求显示窗口缩小时对应的布局:其他浏 ...