依赖注入

依赖注入

动机 

依赖注入主要是为了解决使用者对服务的具体实现的依赖,解除使用者对服务的具体实现的依赖. 

基本思想

依赖注入通过一个单独的装配器来获取服务的具体实现,并将获取的实例配置给使用者.这样解除了使用者和服务的具体实现之间的依赖关系,使用者和服务之间通过接口的契约进行关联.一旦定义好接口,两者之间就是透明的.

实现方式 

        构造子注入:使用者类必须声明一个构造函数,其中包含所有需要注入的元素.PicoContainer容器推荐采用这种方式.

        设置方法注入:使用者类提供一个设值方法,接受需要注入的元素作为参数.Spring容器推荐采用这种方式. 

        接口注入:服务组件必须提供一个接口,此接口只有一个方法,接受需要注入的服务组件接口作为参数,任何服务的使用者必须实现这个接口.装配器通过这些接口将使用者和服务关联起来.如Avalon就采用类似的方式.

服务定位器 

基本思想 

服务定位器的基本思想是有一个单独的服务器知道如何获取使用者需要的所有服务,使用者通过服务定位器类实例获取服务的具体实现,从而解除使用者和服务的依赖关系。但是和依赖注入不同的是使用者必须依赖定位服务器。

实现方式 

        静态服务定位器:将服务定位器实现成一个单例的注册表,此种简单的实现方式有一个问题就是,使用者必须依赖的整个服务定位器,虽然他只使用服务定位器的部分服务,可以通过针对这项服务提供一个简单独立的接口解决。 
 
        动态服务定位器:服务定位器通过映射保存服务信息,可以向他注册需要的服务,并在运行时决定需要使用的服务。这种方式具有很好的灵活性,但是使用者必须通过字符串关键字标识需要使用的服务。

        通过依赖注入解除使用者对服务定位器类的依赖。 

依赖注入还是服务定位器?

        两者之间关键的区别是,使用服务定位器模式,使用者必须依赖于服务定位器,虽然服务定位器可以隐藏服务的具体实现,但是使用者还是必须首先知道服务定位器。然而使用依赖注入,组件和装配器之间没有依赖关系。因此选择的依据应该是对服务定位器的依赖是否会造成问题。

        服务定位器模式把使用者对服务的依赖隐藏在内部,对外是透明的(采用依赖注入实现使用者对服务定位器的了解例外)。对于一个比较复杂的系统,如果需要了解组件之间的关系,是比较困难的,必须遍历代码使用服务定位器的组件。使用依赖注入可以通过构造子和设值方法了解组件之间的关系,或者通过装配器了解组件之间的关系。

        依赖注入的优点是实现了关注点的分离,也就是将组件之间的关系分离出来,作为一个整体由装配器来负责。

构造子注入还是设值方法注入?

构造子注入和设值方法的选择折射出一个问题:我们应该在哪里填充对象的字段?通过构造子初始化的好处是可以明确地告诉如何创建一个合法的对象,另一个好处是可以隐藏任何不可变的字段(通过不提供设置方法),如果通过设值方法完成初始化,暴露出来的设置方法可能会由于误用而造成意料之外的问题。缺点是参数太多会造成构造子比较混乱,如果要传入字符串这样的简单类型,只能通过参数的位置来识别参数的含义,显然这会给使用者造成困扰。个人觉得应该优先采用构造子注入。

结论和思考

许多轻量级容器都使用了依赖注入模式组装应用程序所需要的服务。开发应用程序时,服务定位器模式更加直观。如果开发的组件需要发布给许多程序使用,采用依赖注入模式会是更好的选择。

如果采用依赖注入模式,应该首先考虑构造子注入的方式,特定情况下,采用设值方法注入的方式。

依赖注入和服务定位器模式的选择并不是最重要的,关键是如果需要把选择具体实现类的决策推迟到部署阶段,需要使用插入技术,分离服务的装配和应用程序内部对服务的使用。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值