• PHP 依赖注入,依赖反转 (IOC-DI)


    https://my.oschina.net/u/3529405/blog/1821744

    <?php
    /**
     * 依赖注入 IOC DI
     * 参考文章
     * https://segmentfault.com/a/1190000002411255
     * https://segmentfault.com/a/1190000002424023
     */
    
    /**
     * IOC
     * 控制反转 Inversion of Control
     * 依赖关系的转移
     * 依赖抽象而非实践
     * 比较实用的注入方式有三种
     * Setter injection 使用setter方法
     * Constructor injection 使用构造函数
     * Property Injection 直接设置属性
     */
    
    // IOC 栗子
    // 假设一个储存业务
    
    // 定义接口 业务需求一个数据储存 到rides 或者 mysql 中
    interface SaveIO {
        public function set ();
    }
    // 定义两种储存方式 并继承(implements)SaveIO 接口
    // rides
    class RidesClass implements SaveIO {
        public function set () {
            echo 'rides_save'.PHP_EOL;
        }
    }
    // mysql
    class MysqlClass implements SaveIO {
        public function set (){
            echo 'mysql_save'.PHP_EOL;
        }
    }
    
    // 高层业务
    class Business {
        private $myBusiness;
        public function __construct ($ioc) {
            $this->myBusiness = $ioc;
        }
        public function save () {
            $this->myBusiness->set();
        }
        // 替换依赖
        public function replaceIOC ($ioc) {
            $this->myBusiness = $ioc;
        }
    }
    echo 'IOC------'.PHP_EOL;
    $bus = new Business(new RidesClass());
    $bus->save(); // 输出rides_save
    
    // 替换成其他依赖
    $bus->replaceIOC(new MysqlClass());
    $bus->save(); // 输出 mysql_save
    
    /**
     * DI
     * 依赖注入 Dependency Injection
     * 容器自动根据配置,将依赖注入指定对象
     * 管理应用程序中的『全局』对象(包括实例化、处理依赖关系)。
     * 可以延时加载对象(仅用到时才创建对象)。
     * 促进编写可重用、可测试和松耦合的代码。
     */
    // 首先需要一个容器
    class ConComponent {
        protected $_di = array();
        // 注册 依赖 让依赖存储在$_di 存储形式 $_di->['服务名称']->Closure
        public function register ($name,$service) {
            $this->_di[$name] = $service;
        }
    
        /**
         * public function save ($name)
         * 高层业务,可以另外拓展一个类,不要放在容器里
         * (这里只是一个简易的写法,但是不要这样写)
         * 实现 class{
         * $构造函数=容器返回依赖
         * 高层业务根据需求
         * 通过$_di[className]()创建依赖类
         * 通过$_di[className]()->实现业务
         * }
         * @param $name
         */
        public function save ($name) {
           $this->_di[$name]()->set();
        }
    }
    /*
     * 重复利用 RedisClass MysqlClass
     * 注册依赖
     * */
    $component = new ConComponent(); // 创建容器
    
    /*
     * 注册依赖
     * @param name 依赖的名称
     * @param function(){} 是一个闭包(closure)
     * 所以只有在我们调用一次 $component->_di[name]
     * 才会创建一个依赖对象 实现需时创建
     * */
    $component->register('RedisClass',function () {
        return new RidesClass();
    });
    $component->register('MysqlClass',function () {
        return new MysqlClass();
    });
    echo 'di----'.PHP_EOL;
    $component->save('RedisClass'); // 输出rides_save
    $component->save('MysqlClass'); // 输出Mysql_save
    
    /**
     * AOP
     * Aspect-oriented programming
     * 面向方面编程
     * 无需修改任何一行程序代码,
     * 将功能加入至原先的应用程序中,
     * 也可以在不修改任何程序的情况下移除
     */
  • 相关阅读:
    关于添加类目
    关于协议传值
    Block传值
    UIImagePickerController(相册的使用)
    Handler(单例传值)
    UISearchController
    org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.microsoft.sqlserver.jdbc.SQLServerDriver '
    vs2015 打开项目自动运行 npm install
    Apktool下载与安装 windows环境
    React-Native 问题随记2: com.android.builder.testing.api.DeviceException
  • 原文地址:https://www.cnblogs.com/yszr/p/10680464.html
Copyright © 2020-2023  润新知