ioc和di的区别和关系(深入浅出之控制反转)

控制反转(Inversion of Control,缩写为IoC)和依赖注入(Dependency Injection)在当今软件工程中占有举足轻重的地位,两者之间有着密不可分的联系。

接下来将深入浅出,举例说明什么是控制反转,什么是依赖注入,以及它们之间的关系。

什么是依赖注入?

依赖注入就是参数传递

上面的定义你也许会感到惊讶,就这?是的,就是这么简单。依赖注入是在一个类中以参数传递的形式引入另外的类,它本身是参数传递的一种形式。但是,反过来就不成立,参数传递不一定是依赖注入,可能是普通的参数,而非某个类。可能这么定义还不够清晰,下面的代码将帮助你理解,

class IocTest{ protected $logger; public function __constructor(DbLogger $logger){ $this->logger = $logger; } public function hello(){ $this->logger->hello(); } }

这里的IocTest类,通过依赖注入的方式引用了DbLogger类,这里假设DbLogger是将日志写入数据库。代码使用PHP编写,本身比较简单,可以使用任何面向对象的编程语言改写。

什么是控制反转?
  • 高等级的代码不能依赖低等级的代码;
  • 抽象接口不能依赖具体实现;

上面是控制反转的定义,同样比大多数文章描述的简单,定义本该这么简洁。所谓高等级的代码,可以理解为抽象类、接口、装饰类等等;所谓低等级的代码,可以理解为抽象类的具体实现,定义具体功能的类。这么说可能还是不够直观,还是举例说明,

ioc和di的区别和关系(深入浅出之控制反转)(1)

IoC&DI

这张图比较主观的说明了什么是控制反转和依赖注入,同时也很好的说明了它们之间的关系。如果IocTest类依赖具体的类DbLogger,代码完全失去了灵活性,当我们需要将日志输出到文件,需要创建一个新的IocTest类,将依赖的DbLogger改成FileLogger,

class IocTest{ protected $logger; public function __constructor(FileLogger $logger){ $this->logger = $logger; } public function hello(){ $this->logger->hello(); } }

要解决这个问题,需要对DbLogger和FileLogger进行抽象,IocTest类依赖抽象类LoggerInterface,这样就实现了代码的解耦,IocTest不需要强依赖于具体类,增加了可扩展性。

总结
  • 控制反转解决代码的强耦合,增加了代码的可扩展性,这也就是为什么当今流行的框架Spring Boot和Laravel底层都是采用IoC;
  • 控制反转是为了实现更灵活的依赖注入,而非消灭依赖注入;
  • 当解决过度依赖,对具体类进行抽象的时候,便产生了Ioc,之后依赖注入的是抽象类。
,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页