存在两种设计模式,即依赖注入和依赖性反转,文章在网上试图解释差异.但是,用更容易的话来解释它的必要性仍然存在.那里有人来接?

我需要在PHP中理解它.

(注意:这个答案与语言无关,虽然问题特别提到PHP,但是对PHP不熟悉,我没有提供任何PHP示例).

注射与反转

> Dependency Injection是一种Inversion of Control技术,用于通过Dependency Injection Design Pattern向类提供对象(‘dependencies’).通常通过以下方法之一传递依赖项:

>构造函数
>公共财产或领域
>公共二传手

>依赖倒置原则(DIP)是一个软件设计指南,归结为关于de-coupling a class from its concrete dependencies的两个建议:

>’高级模块不应该依赖于低级模块.两者都应该取决于抽象.
>’抽象不应该依赖于细节.细节应该取决于抽象.

依赖注入

首先,依赖注入与控制反转(IoC)不同.具体来说,IoC是不同解决方案的保护伞,包括依赖注入,服务定位器,工厂模式,策略模式等.

考虑到依赖注入而设计的类可能如下所示:

// Dependency Injection Example...

class Foo {
    // Constructor uses DI to obtain the Meow and Woof dependencies
    constructor(fred: Meow,barney: Woof) {
        this.fred = fred;
        this.barney = barney;
    }
}

在这个例子中,Meow和Woof都是通过Foo构造函数注入的依赖项.

另一方面,没有依赖注入设计的Foo类可能只是创建Meow和Woof实例本身,或者可能使用某种服务定位器/工厂:

// Example without Dependency Injection...

class Foo {
    constructor() {
        // a 'Meow' instance is created within the Foo constructor
        this.fred = new Meow();

        // a service locator gets a 'WoofFactory' which in-turn
        // is responsible for creating a 'Woof' instance.
        // This demonstrates IoC but not Dependency Injection.
        var factory = TheServiceLocator.GetWoofFactory();
        this.barney = factory.CreateWoof();
    }
}

因此,依赖注入只是意味着一个类已经推迟了获取或提供自己的依赖关系的责任;相反,责任在于任何想要创建实例的东西. (通常是IoC容器)

依赖倒置

依赖性反转通常是通过防止那些具有彼此直接引用的类来解除具体类的分离.

注意:依赖性反转通常在静态类型编程语言(如C#或Java)中更明确,因为这些语言对变量名执行严格的类型检查.另一方面,依赖性反转已经在动态语言(如Python或JavaScript)中被动地可用,因为这些语言中的变量没有任何特定的类型限制.

考虑使用静态类型语言的场景,其中类需要能够从应用程序的数据库中读取记录:

class Foo {
    reader: sqlRecordReader;

    constructor(sqlReader: sqlRecordReader) {
        this.reader = sqlReader;
    }

    doSomething() {
        var records = this.reader.readAll();
        // etc.
    }
}

在上面的例子中,类Foo对sqlRecordReader有很强的依赖性,但它唯一关心的是存在一个名为readAll()的方法,它返回一些记录.

考虑将sql数据库查询分成单独的微服务的情况; Foo类需要从删除服务中读取记录.或者,Foo单元测试需要从内存存储或平面文件中读取数据的情况.

如果顾名思义,sqlRecordReader包含数据库和sql逻辑,那么任何迁移到微服务都需要改变Foo类.

依赖性反转指南建议应该用仅提供readAll()方法的抽象替换sqlRecordReader.即:

interface IRecordReader {
    Records[] getAll();
}

class Foo {
    reader: IRecordReader;

    constructor(reader: IRecordReader) {
        this.reader = reader;
    }
}

根据DIP,IRecordReader是一个抽象,并且强制Foo依赖于IRecordReader而不是sqlRecordReader满足DIP指南.

为什么DIP指南很有用

关键字是指南 – 依赖性反转将间接添加到程序的设计中.添加任何类型的间接的明显缺点是复杂性(即,人类理解正在发生的事情所需的认知“负荷”)增加.

在许多情况下,间接可以使代码更容易维护(修复错误,添加增强功能)但是:

在最后一个例子中,Foo可能会收到一个sqlRecordReader,或者一个SoapRecordReader,或者一个FileRecordReader,或者甚至可能用于单元测试一个MockRecordReader – 重点是它不知道或关心IRecordReader的不同可能实现 – 提供当然,这些实现完全符合Liskov Substitution Principle.

此外,它避免了潜在的肮脏场景,即急于开始工作的开发人员可能会考虑通过从基类sqlRecordReader继承SoapRecordReader或FileRecordReader来“捏造”Liskov原则.

更糟糕的是,缺乏经验的开发人员甚至可能会更改sqlRecordReader本身,以便该类不仅具有sql逻辑,还具有SOAP端点,文件系统以及可能需要的任何其他内容. (这种事情在现实世界中经常发生 – 特别是在维护不良的代码中,并且几乎总是Code Smell.)

php – 依赖注入和依赖项反转之间的区别的更多相关文章

  1. Spring IOC容器的Bean管理基于注解属性注入方式

    这篇文章主要为大家介绍了Spring IOC容器的Bean管理基于注解属性注入方式,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  2. Spring IOC容器Bean管理的完全注解开发放弃配置文件

    这篇文章主要为大家介绍了Spring IOC容器的Bean管理完全注解开发放弃配置文件,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  3. 向Spring IOC 容器动态注册bean实现方式

    这篇文章主要为大家介绍了向Spring IOC 容器动态注册bean实现方式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. Spring IOC 能降低耦合的问题分析及解决方法

    这篇文章主要介绍了Spring IOC 为什么能降低耦合,依赖注入是调用者仅通过声明某个组件就可以获得组件的控制权,而对该组件的依赖关系管理、查找、加载由外部完成,需要的朋友可以参考下

  5. Spring IOC 常用注解与使用实例详解

    这篇文章主要介绍了Spring IOC 常用注解与使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Spring使用IOC与DI实现完全注解开发

    IOC也是Spring的核心之一了,之前学的时候是采用xml配置文件的方式去实现的,后来其中也多少穿插了几个注解,但是没有说完全采用注解实现。那么这篇文章就和大家分享一下,全部采用注解来实现IOC + DI

  7. 深入了解Spring控制反转IOC原理

    IOC-Inversion of Control,即控制反转。它不是什么技术,而是一种设计思想。这篇文章将为大家介绍一下Spring控制反转IOC的原理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  8. spring IOC容器的Bean管理XML自动装配过程

    这篇文章主要为大家介绍了spring IOC容器Bean管理基于XML的自动装配过程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  9. IOC 容器启动和Bean实例化两个阶段详解

    这篇文章主要为大家介绍了IOC 容器启动和Bean实例化两个阶段详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. Spring的IOC原理详情

    这篇文章主要介绍了Spring的IOC原理详情,IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”,还有些书籍翻译成为控制反向或者控制倒置

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部