如果你之前使用过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

最新文章

  1. 超简单的激活Microsoft Office 2016 for Mac 方法
  2. ios 开发中 动态库 与静态库的区别
  3. SQL 计算两个地理坐标相差的距离的函数
  4. My97日期控件 选择日期区间
  5. HDU 5510 Bazinga (字符串匹配)
  6. MySQL多实例-精典故障案例
  7. iOS 之 NSUserDefault
  8. laravel中token的使用方式
  9. 【JAVASCRIPT】React学习-如何构建一个组件
  10. angular.js基础
  11. OpenStack_I版 7.Cinder部署
  12. db2数据库备份与恢复
  13. Spring Boot(十二)单元测试JUnit
  14. 殊途同归 - Church-Rosser and Consistency of Evaluation
  15. 18-09-16如何从pychram的第三方包导入设计器
  16. RPM打包原理、示例、详解及备查
  17. React 表单与事件
  18. SQL RAISERROR 用法
  19. 关于connect by 误区讲解,纯属个人心得和经验,有图有文字
  20. CI框架视图继承

热门文章

  1. 2.8. 创建 NSManagedObject 的子类 (Core Data 应用程序实践指南)
  2. iOS 英语
  3. pureMVC简单示例及其原理讲解五(Facade)
  4. Node.js理解
  5. jquery属性的相关js实现方法
  6. java服务器获取客户端ip
  7. HDU4496(并查集)
  8. 远程控制TOMCAT启动
  9. zstuoj 4243
  10. jq基础