资讯专栏INFORMATION COLUMN

OOD、DIP、IOC、DI、依赖注入容器(即 控制反转容器,IOC Container)

renweihub / 1887人阅读

摘要:服务本省作为一个高层类,对外提供访问,却受制于提供具体服务的服务提供者定义的实现,高层模块依赖底层模块实现,违背了依赖倒置原则。遵循依赖倒置原则的例子场景同介绍中场景。

1. 名词介绍

OOD,面向对象设计

DIP,依赖倒置(软件设计原则)

IOC,控制反转(软件设计模式)

DI,依赖注入

IOC Container,控制反转容器,也是依赖注入容器

2. 组成部分

服务清单(功能清单,service list)

服务(高层类,service ,对外提供服务)

服务提供者(底层类,service provider ,实际提供服务的对象)

2. 依赖倒置原则(DIP) 2.0 介绍

依赖倒置原则,它转换了依赖,高层模块不依赖于低层模块的实现,而低层模块依赖于高层模块定义的接口

详细介绍请点我

2.1 场景描述

提供一个计算机储存的服务。需要根据不同的用户需求,使用不同的存储设备。

2.2 没有遵循依赖倒置原则的例子 2.2.1 定义好服务提供者(实际提供服务)
// 定义一个 硬盘存储类 (服务提供者)
class HardDiskStorage {
    public function saveToHardDisk(){
        
    }
    
    public function readFromHardDisk(){
        
    }
}

// 定义一个 U盘存储类(服务提供者)
class UStorage {
    public function saveToU(){
        
    }
    
    public function readFromU(){
        
    }
}
2.2.2 定义 服务(对外提供服务的对象)
/**
 * 定义一个 ComputerStorage 类(存储服务)
 */ 

// 第一种:使用硬盘作为提供实际服务的对象
class ComputerStorage {
    protected $_storage = null;
    
    function __construct(){
        $this->_storage = new HardDiskStorage();
    }
    
    public function save(){
        $this->_storage->saveToHardDisk();
    }
    
    public function read(){
        $this->_storage->readFromHardDisk();
    }
}

// 第二种:使用 U 盘作为提供实际服务的对象
class ComputerStorage {
    protected $_storage = null;
    
    function __construct(){
        $this->_storage = new UStorage();
    }
    
    public function save(){
        $this->_storage->saveToU();
    }
    
    public function read(){
        $this->_storage->readFromU();
    }
}

// 读取
$cs = new ComputerStorage();
$cs->read();
2.2.3 代码分析

根据上面的代码,当切换服务提供者时,服务类的代码需要做较多的改动。服务(ComputerStorage)本省作为一个高层类,对外提供访问,却受制于提供具体服务的服务提供者(HardDiskStorageUStorage)定义的实现(saveToHardDisksaveToUreadFromHardDiskreadFromU),高层模块依赖底层模块实现,违背了依赖倒置原则。

2.3 遵循依赖倒置原则的例子 2.3.1 场景

2.1 介绍中场景。

2.3.2 定义服务清单(高层模块定义接口)
interface ServiceList {
    public function save();
    public function read();
}
2.3.3 定义服务提供者
// 硬盘
class HardDiskStorage implements ServiceList {
    public function save(){
        
    }
    
    public function read(){
        
    }
}

// U 盘
class UStorage implements ServiceList {
    public function save(){
        
    }
    
    public function read(){
        
    }
}
2.3.4 定义服务
class ComputerStorage {
    protected $_storage = null;
    
    function __construct(){
        $this->_storage = new HardDiskStorage();        
    }
    
    public function save(){
        $this->_storage->save();
    }
    
    public function read(){
        $this->_storage->read();
    }
}

$cs = new ComputerStorage();
$cs->read();
2.3.5 代码分析

上述代码中,事先定义了好了服务清单(接口,ServiceList),然后服务提供者实现这些接口(HardDiskStorageUStorage),服务(ComputerStorage)只需要切换服务提供者即可(HardDiskStorageUStorage),完全无需理会他们的实现(readFromHardDiskreadFromU...等)。高层模块不依赖于底层模块定义的实现,遵循了依赖倒置原则

3. 控制反转(IOC) + 依赖注入(DI) 3.0 介绍

控制反转(IoC),它为相互依赖的组件提供抽象,将依赖(低层模块)对象的获得交给第三方(系统)来控制,即依赖对象不在被依赖模块的类中直接通过new来获取

详细介绍请点我

3.1 场景

2 场景

3.2 没有实现控制反转的例子

2 中的例子就是没有实现控制反转的例子。2ComputerStorage 获取依赖(HardDiskStorageUStorage)的途径都是在 contruct 构造函数中获取的,即 类内部实例化依赖获取。

3.3 实现控制反转的例子

以下代码是根据 2 中的代码做了些许的调整。

class ComputerStorage {
    protected $_storage = null;
    
    /**
     * 内部只获取依赖的实例
     */
    public function setStorage($storage){
        $this->_storage = $storage;
    }

    public function save(){
        $this->_storage->save();
    }
    
    public function read(){
        $this->_storage->read();
    }
}

// 外部实例化依赖
$hardDiskStorage = new HardDiskStorage();

$cs = new ComputerStorage();
// 注入依赖
$cs->setStorage($hardDiskStorage);
4. 依赖注入容器(IOC 容器) 4.0 场景

2 场景。

4.1 使用 IOC容器
class Container {
    // 注册表
    protected static $_registry = null;
    
    // 保存到注册表
    public static function set($classname , Callable $create){
        self::$_registry[$classname] = $create;
    }
    
    // 获取注册表对应类的实例
    public static function get($key){
        call_user_func(self::$_registry[$key]);
    }
}

class ComputerStorage {
    protected $_storage = null;
    
    function __construct(){
        $this->_storage = Container::get("HardDiskStorage");
    }
    
    public function read(){
        $this->_storage->read();
    }
    
    public function save(){
        $this->_storage->save();
    }
}

/**
 * 注册依赖
 */
Container::set("HardDiskStorage" , function(){
    return new HardDiskStorage();
});

Container::set("UStorage" , function(){
    return new UStorage();
});

// 测试
$cs = new ComputerStorage();

$cs->read();

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/25788.html

相关文章

  • Yii2中的依赖注入

    摘要:构造器注入实现特定参数的构造函数,在新建对象时传入所依赖类型的对象。 基本概念 1.依赖倒置(反转)原则(DIP):一种软件架构设计的原则(抽象概念,是一种思想)在面向对象编程领域中,依赖反转原则(Dependency inversion principle,DIP)是指一种特定的解耦(传统的依赖关系创建在高层次上,而具体的策略设置则应用在低层次的模块上)形式,使得高层次的模块不依赖于...

    harriszh 评论0 收藏0
  • 搞懂依赖注入, 用 PHP 手写简易 IOC 容器

    摘要:依赖注入控制反转的一种具体实现方法。接下来,我们使用依赖注入实现控制反转,使依赖关系倒置依赖被动传入。从单元测试的角度看,依赖注入更方便和操作,方便了测试人员写出质量更高的测试代码。 前言 好的设计会提高程序的可复用性和可维护性,也间接的提高了开发人员的生产力。今天,我们就来说一下在很多框架中都使用的依赖注入。 一些概念 要搞清楚什么是依赖注入如何依赖注入,首先我们要明确一些概念。 D...

    antz 评论0 收藏0
  • Yii源码解读-依赖注入容器

    摘要:在中使用解耦,有两种注入方式构造函数注入属性注入。对象的实例化解析依赖信息该方法实质上就是通过的反射机制,通过类的构造函数的参数分析他所依赖的单元。 有关概念 依赖倒置原则(Dependence Inversion Principle, DIP) 传统软件设计中,上层代码依赖于下层代码,当下层出现变动时,上层也要相应变化。 DIP的核心思想是:上层定义接口,下层实现这个接口,从而使的下...

    Prasanta 评论0 收藏0
  • Laravel中的核心概念

    摘要:可以为服务提供者的方法设置类型提示。方法将在所有其他服务提供者均已注册之后调用。所有服务提供者都在配置文件中注册。可以选择推迟服务提供者的注册,直到真正需要注册绑定时,这样可以提供应用程序的性能。 本文最早发布于 Rootrl的Blog 导言 Laravel是一款先进的现代化框架,里面有一些概念非常重要。在上手Laravel之前,我认为先弄懂这些概念是很有必要的。你甚至需要重温下PHP...

    ddongjian0000 评论0 收藏0
  • 聊一聊PHP的依赖注入(DI) 和 控制反转(IoC)

    摘要:前言最近在使用框架,看了下他的源码,发现有很多地方也用到了依赖注入控制反转,觉得有必要和大家简单聊一聊什么是依赖注入以及怎么使用它。概念依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。 前言 最近在使用ThinkPHP5框架,看了下他的源码,发现有很多地方也用到了依赖注入(控制反转),觉得有必要和大家简单聊一聊什么是依赖注入以及怎么使用它。 简介 I...

    sixgo 评论0 收藏0

发表评论

0条评论

renweihub

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<