当前位置: 首页 > 后端技术 > PHP

深入理解IoC(InversionofControl)、DI(DependencyInjection)

时间:2023-03-29 23:13:30 PHP

引用最近在看设计模式和laravel代码。之前对InversionofControl和DependencyInjection的概念很困惑,于是找了一些资料。下面是关于InversionofControl的理解。概念IoC控制反转(InversionofControl,简称IoC)是面向对象程序设计中的一个设计原则,可以用来降低计算机代码之间的耦合度。它将传统上由程序代码直接操作的对象的调用权赋予容器,通过容器实现对象组件的组装和管理。所谓“控制反转”的概念就是将组件对象的控制权从程序代码本身转移到外部容器。最常见的一种方式叫做依赖注入(DependencyInjection,简称DI),还有一种方式叫做“依赖查找”(DependencyLookup)。通过控制反转,当一个对象被创建时,它所依赖的对象的引用由一个外部实体传递给它,这个外部实体调节系统中的所有对象。也可以说依赖注入到对象中。如概念中所述,控制反转具体是指哪些控制被反转。其实我理解的控制反转就是把程序控制的对象的控制权交给了容器,而这个容器就是实现各个模块的解决方案。耦合的关键。IoC只是一种设计思想,其主要实现有:DependencyLookup:容器为组件提供回调接口和上下文。依赖注入(DependencyInjection)让我们关注依赖注入。DI在软件工程中,依赖注入是一种设计模式,它实现控制反转来解决依赖关系。依赖关系是指可以被利用的对象(即服务提供者)。依赖注入是将依赖传递给将要使用的依赖对象(即客户端)。该服务是将成为客户端的状态的一部分。向客户提供服务,而不是让客户创建或查找服务,是这种设计模式的基本要求。以上是维基百科上对依赖注入的理解,下面结合实际例子详细讲解。比如我们设计一个通用的用户登录基类,可以支持多平台用户登录,那么最糟糕的写法就是,/***ClassAuserlogin**/classUser_A_Login{publicfunctioncheckALogin(){};}/***B类用户登录**/classUser_B_Login{publicfunctioncheckBLogin(){};}/***登录基类**/classUser_Login{publicfunctioncheckLogin($userType){if($userType='A'){$this->objAUser=newUser_A_Login();$this->objAUser->checkALogin();}elseif($userType='B'){$this->objBUser=newUser_B_Login();$this->objBUser->checkBLogin();}}}上面的User_Login类直接依赖于User_A_Login和User_B_Login类,如果我们用下面的方法写interfaceUser_Login_Interface{publicfunctioncheckLogin();}/***A类用户登录**/classUser_A_LoginimplementsUser_Login_Interface{publicfunctioncheckLogin(){};}/***B类用户登录**/classUser_B_Login实现User_Login_Interface{publicfunctioncheckLogin(){};}/***登录基类**/classUser_Login{公共$用户登录;publicfunctionsetUser(User_Login_Interface$user){$this->userLogin=$user;}publicfunctioncheckLogin(){$this->userLogin->checkLogin();如果您以这种方式构建代码,我们通过函数setUser()将依赖项User_B_Login或User_A_Login注入到类中,调用方法:$userLogin=newUser_Login();$userLogin->setUser(newUser_A_Login);$userLogin->checkLogin();调用者可以控制使用哪种登录类型,从而完成对不同登录系统的依赖注入。如果引入一个新的用户c,就写一个c的登录类:/***C类用户登录**/classUser_C_LoginimplementsUser_Login_Interface{publicfunctioncheckLogin(){};}可以通过:$userLogin=newUser_Login();$userLogin->setUser(newUser_C_Login);$userLogin->checkLogin();用于登录验证。在实际代码中,由于基类非常复杂,需要对登录做一系列处理,所以每次添加登录用户时,基类都不要修改。对于laravel这样的框架,是不能修改的,应该是通过这种方式实现的调用者的自定义。