依赖注入(DI)和控制反转(IoC)

1273 2023年09月26日 后端

每个新技术的诞生,都是为了解决已存在的问题,在此开始之前,先让我们来看一下下面例子:

interface PersonInterface {
    public function eat();
}

class Dog implements PersonInterface {
    public function eat() {
        echo "Dog eat";
    }
}

class Cat implements PersonInterface {
    public function eat() {
        echo "Cat eat.";
    }
}

class PersonFactory {
    public function getPerson($PersonType) {
        if($PersonType == null) {
            return null;
        } else if($PersonType == "Dog") {
            return new Dog();
        } else if($PersonType == "Cat") {
            return new Cat();
        }
    }
}

$PersonFactory = new PersonFactory();
$Dog = $PersonFactory->getPerson("Dog");
$Dog->eat();
$Cat = $PersonFactory->getPerson("Cat");
$Cat->eat();

以上代码存在的问题是,每增加一个Person,则需要在工厂类PersonFactory增加配置。虽然以上代码使用了工厂模式有所优化,但配置不能解耦,不是我们想要的最优效果。

概念:

依赖注入(Dependency Injection,简称DI)是一种设计模式,它允许我们在代码中去除硬编码的依赖关系,并使这些关系变得更加灵活和可配置。依赖注入通过将依赖关系(例如对象、变量或服务等)作为参数传递给需要它们的对象,从而实现解耦和可测试性。

控制反转(Inversion of Control,简称IoC)是一种设计原则,它将控制权从代码本身转移到外部容器中,该容器负责创建和管理对象及其依赖关系。控制反转通过将对象的创建和管理交给外部容器来完成,从而减少了类之间的耦合,并使代码更加可维护和可扩展。

概率理解:

依赖注入:假设你是一个汽车制造公司的经理,你有一个引擎部门、轮胎部门、车身部门等等。这些部门都需要协作才能生产出一辆完整的汽车。如果你要求每个部门都直接与其他部门进行通信,那么代码的耦合度就会很高,而且也很容易出错。因此,你可以使用依赖注入。在依赖注入中,你创建了一个中央控制中心(或者说是一个容器),它负责协调各个部门的工作。每个部门只需要关注自己的工作,而不需要知道其他部门的事情。当一个部门需要其他部门的支持时,它只需要向中央控制中心申请就可以了,不需要直接与其他部门进行通信。

控制反转:在控制反转中,你创建了一个中央控制中心(或者说是一个容器),它负责管理各个部分的生命周期(也就是说什么时候创建、什么时候销毁等等)。这样,你就将控制权从代码本身转移到了外部的中央控制中心。这个中央控制中心可以根据需要创建和销毁对象,而不需要在代码中硬编码这些操作。这样的好处是,你的代码变得更加简洁、可维护和可测试。

代码实现:

interface PersonInterface {
    public function eat();
}

class Person {
    private $person;  
  
    public function __construct(PersonInterface $person) {  
        $this->person = $person;  
    }  
    
    public function eat(){
        $this->person->eat();
    }
}

class PersonFactory {  
    private $person;  
  
    public function __construct(PersonInterface $person) {  
        $this->person = $person;  
    }  
  
    public function createPerson() {  
        return new Person($this->person);  
    }  
}  

class Dog implements PersonInterface {
    //Dog实体
}

class Cat implements PersonInterface {
    //Cat实体
}

// 使用工厂创建Person对象并注入依赖关系  
$factory = new PersonFactory(new Dog());  
$dog = $factory->createPerson();
$dog->eat();

$factory = new PersonFactory(new Cat());  
$cat = $factory->createPerson();
$cat->eat();

在上述示例中,PersonFactory是工厂类,负责创建Person对象并注入依赖关系。

通过将Dog和Cat对象传递给FooFactory,我们实现了控制反转,将对象的创建逻辑从Person类中移出,并由工厂类来管理。

评论

0 条评论
OBJUI公众号
热门文章
  • 使用Echarts画甘特图

    Echarts是一个非常强大的图表库, 下面我们来使用它来画甘特图,

  • go语言怎么连接mysql,并实现增删改查

    要使用Go语言连接MySQL,需要使用第三方库。常用的库包括: 这里以go-sql-driver/mysql为 […]

  • beego实现模块化开发

    Beego 框架可以通过模块化开发来提高项目的可维护性和可扩展性,可以将一个大型的应用划分为多个模块,每个模块独立维护,有自己的控制器、视图和模型等。

  • Beego实现JWT

    Beego是一个基于Go语言的Web框架,实现JWT认证可以通过beego的中间件机制来实现,下面是一个简单的 […]

  • 使用Axios+PHP+JWT实现登录认证

    JWT(JSON Web Token),顾名思义就是可以在Web上传输的token,这种token是用JSON格式进行format的。它是一个开源标准(RFC7519),定义了一个紧凑的自包含的方式在不同实体之间安全的用JSON格式传输信息。

  • PHP解决雪花算法ID在前端精度丢失的问题

    雪花算法(Snowflake)是一种用于生成全局唯一ID的算法,其基本思路是结合时间戳、机器ID、租约ID和序列号生成一个64位的数据,从而保证ID的唯一性。 雪花算法的生成过程如下:

  • 虚拟滚动实现页面百万数据滚动

    1.概念 虚拟滚动是一种优化长列表性能的技术,它通过按需渲染的方式,只渲染可见部分的列表项,而不是渲染整个列表 […]

  • go实现MD5

    在这个示例中,我们使用了Go标准库中的crypto/md5包来计算一个字符串的MD5值。首先,我们将字符串转换 […]

  • Linux服务器Rsync结合inotify同步文件

    一、实现效果 服务器A:192.168.161.150 (分布服务器)(rsync客户端+inotify) 服务器B:192.168.161.151 (WEB服务器1)(rsync服务端) 服务器C:192.168.161.152 (WEB服务器2)(rsync服务端) 说明:服务器A有文件更新,自动同步到服务器B和C

  • JavaScript实现滑动验证码

    滑动验证码(也叫做滑动拼图验证码)是一种用户交互形式的验证码,通常用于网页或移动应用的登录、注册或敏感操作。其 […]