Dependency Injection & Inversion of Control 是Martin Fowler在2004年所提出來的一个概念,Martin Fowler在这篇文章中指出,DI可以有三种形式来实现。这观念以后有Spring项目和Google实现出来,变成了Java Enterprise应用中不可或缺的一部分。
控制反转是一个重要的面向对象编程的法则来 削减计算机程序的耦合问题 。控制反转一般分为两个类型,依赖注入(Dependency Injection)和依赖查找(Dependency Lookup)。依赖注入应用广泛。
许多应用程序都是由两个或更多的类通过彼此的合作来实现业务逻辑,这使得每个对象都需要与其合作的对象(也就是它做依赖的对象)的引用。如果这个获取过程要靠自身实现,那么这将导致代码高度耦合并且难以测试。应用控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用,传递给它。也可以说,依赖被注入到对象中。所以,控制反转是关于一个对象如何获取它所依赖的对象的引用——这个责任的反转。
IoC模式,系统中通过引入实现了IoC模式的IoC容器,即可由IoC容器来管理对象的生命周期、依赖关系等,从而使得应用程序的配置和依赖性规范与实际的应用程序代码分开。其中一个特点就是通过文本的配置文件进行应用程序组件间依赖关系的配置,而不用重新修改并编译具体的代码。对于Java程序而言,IoC模式可以看做是工厂模式的升华,可以把IoC看做是一个大工厂,只不过大工厂要生成的对象都是在XML文件中给出定义的,然后利用Java的反射编程,根据XML中给出的类名生成相应的对象。从实现来看,IoC是把以前的工厂方法里写死的对象生成代码,改变为由XML文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。
依赖注入一般需要三个组成部分:
蛋糕模式(cake pattern)是Scala实现依赖注入的方法之一,它利用Scala Mixin功能,让对象被创建时,才把相依的原件,透过Mixin的方式绑在一起。
Config特质定义了load方法和text值,load方法在实例化时将被执行,用于载入配置信息。一个具体的配置类型定义为InMemoryConfig,它定义了具体的Config行为。
traitConfig{ load valtext: String defload: Unit } traitInMemoryConfigextendsConfig{ lazyvaltext ="Hello" defload = println("load: "+ text) }
Context特质用来表示蛋糕模式的内容对象,MyContext特质使用 this
子类型注解(self type annotation)指定Config类型将被混入到当前类或对象中,于是Config特质中的数据和方法就好像是定义在该特质中的一样。
注意,多个特质都可以被混入到this引用中,比如 this: ConfigContext with DAOContext with ConnectionManagerContext
。
traitContext traitMyContextextendsContext{ this: Config => defwelcome =this.text }
Env这个对象是单例模式在Scala中的语法化表示,它继承了混入InMemoryConfig特质的MyContext,它很好的表示了依赖嵌入环境。
objectEnvextendsMyContextwithInMemoryConfig
执行 println(Env.text)
将打印:
load:Hello Hello
Dependency Injection in Scala
转载请注明作者Jason Ding及其出处
jasonding.top
Github博客主页(http://blog.jasonding.top/)
CSDN博客(http://blog.csdn.net/jasonding1354)
简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)
Google搜索jasonding1354进入我的博客主页