zoukankan      html  css  js  c++  java
  • 依赖注入 IOC容器的实现

    由于 我的框架(框架 请看上一篇)使用了两套数据源

    一套是http的接口请求方式,一套是直接链接 mysql的方式

    故而 两套方式,要是想通过配置化的方式就能够实现 数据源的切换,
    进而想到了 依赖注入的方式实现该功能

    最早接触 IOC容器 是由于之前做 .net的时候,那时候听别人讲这些专业名词  觉得挺高大上的,不过不知道它的优势在哪。

    后面深入了解了之后,由于 注入的解耦的特性,以及 它的高扩展性  确实非常高深。

    就像 我们目前做的一个系统,由于之前用的是mysql直接连的数据源,到现在 数据量庞大的时候,发现了它的数据读写瓶颈,可是也很无奈呀。

    想要将数据源移植到 分布式的微服务架构中, 前端上只做一些简单的php处理。可是由于之前的代码扩展性很差,工程量 很庞大,只能开始重构系统了。

    非常痛苦。

    下面通过user 的 数据添加功能进行操作

    依赖注入

    构造注入 

    通过构造方法进行对象注入

    public class UserModels
    {
        private Db $db;
        // 注入
        public function UserModels($server)
        {
            $this->db=$server;
        }
        
        public function add($data)
        {
            $this->db->add($data);
        }
    }
    
    public class UserController
    {
        public addUser()
        {
            $user=array();
            Db mysql=new Mysql();
            
            UserModels usermodels=new UserModels(mysql);
            
            usermodels->add($user);
        }
    }

    属性注入
    通过setter 方法进行对象注入

    public class UserModels
    {
        private Db $db;
        // 注入
        public function setDb($server)
        {
            $this->db=$server;
        }
        public function add($data)
        {
            $this->db->add($data);
        }
    }
    
    public class UserController
    {
        public addUser()
        {
            $user=array();
            Db mysql=new Mysql();
            
            UserModels usermodels=new UserModels();
            usermodels->setDb(mysql);
            usermodels->add($user);
        }
    }

    属性注入的话,就是当你想要注入该对象就注入 不用在我们的对象构造的时候就注入其中,会耦合性更低。
    否则,如果我们一个类 使用了多个对象,那岂不是 构造方法的参数 一堆堆的。。

    接口注入

      接口注入的方式就是通过一个接口进行对象注入

    public interface Models
    {
        public function initDb($server);
    }
    
    public class UserModels implements Models
    {
        private Db $db;
        // 注入
        public function initDb($server)
        {
            $this->db=$server;
        }
        public function add($data)
        {
            $this->db->add($data);
        }
    }
    
    public class UserController
    {
        public addUser()
        {
            $user=array();
            Db mysql=new Mysql();
            
            UserModels usermodels=new UserModels();
            usermodels->initDb(mysql);
            usermodels->add($user);
        }
    }

    发现,这些注入方式的代码 还是不好写,麻烦,想通过配置的方式,底层实现,然后在具体业务上不需要关心我的数据源。。然后 想到了IOC容器,来实现 自动的依赖注入

    java 的spring 框架就是用来做这个事情的。可是 我是php 啊。。怎么办咧。。想要自己实现一套 类似的东西。

    不想用xml 就用 配置的数组吧。

    先添加一个配置文件   

    Ucontainer.php
    <?php
    namespace Config;
    /**
     * IOC容器配置
     * @author
     */
    class Ucontainer
    {
        // 
        public static $db = array(
            'UserModels'    => 'Db',// 或者指向  Api
        );
    
    
    }

    然后添加一个

    Ucontainer.php类 来做注入

    <?php
    namespace Lib;
    
    class UContainer{
    
        /**
        *@intro 通过配置 获取 数据源对象
        *@author kinmos 
        *@time 
        *@param 
        *@return
        */
        public static function getDbInstanse($models)
        {
            $dbContainer=ConfigUcontainer::$db;
            if(isset($dbContainer[$models])&&!empty($dbContainer[$models]))
            {
                $source=str_replace('Models','',$models);
                $classname = "Http\Models\".$dbContainer[$models]."\".$source;
                return new $classname;
            }
        }
    }

    这样 ,在我们的数据层 。定义的Models 文件夹中添加一个UserModels 文件 

    UserModels.php

    <?php
    
    namespace HttpModels;
    use LibUContainer;
    
    class UserModels
    {
        private static $classname='UserModels';
    
        // 获取用户列表
        public static function userList($params=array()){
            
            $data=UContainer::getDbInstanse(self::$classname)->userList();
    
            return $data;
        }
    }

    这样在我们的Models 里面的Db  和 Api 文件夹中各自添加各自方式的数据源

    Api.User.php

    <?php
    
    namespace HttpModelsApi;
    
    class User
    {
    
    
        public function userList($apiReqData = array())
        {
            $result = array();
            //组装API请求的数据
            $apiName = 'User.userList'; //接口的名称
            //请求API,得到返回的数据(数组格式)
            $resultEntity = httpApiGetData($apiName, $apiReqData);
            
            if ($resultEntity['code'] == 200) {
                $result = $resultEntity['data'];
            }
    
            
    
            return $result;
        }
    }

    Db.User.php

    <?php
    
    namespace HttpModelsDb;
    
    use LibDbTable;
    
    /**
     * 
     */
    class User extends DbTable
    {
        protected $_name = 'user';
    
        protected $_primary = 'id';
    
        protected $_db = 'default';
    
        /*
        * 构造函数
        */
        public function __construct()
        {
        }
    
        public function userList($params=array())
        {
            // 查询所有数据
            $list=$this->getList('1=1');
            return $list;
        }
    }

    这样 一个整个简单的容器就搭建起来了。然后在使用上就简单了。

    namespace HttpControllersDemo;
    
    use HttpModelsUserModels;
    
    use HttpControllersActionController;
    
    class IndexController extends ActionController
    {
        
        public function index()
        {
            $data=UserModels::userList();
            print_r($data);die;
        }
    }

    使用上,只需要调用 Models层的数据,就可以了。业务上不需要关系到底 从那个数据源中取数据,

    同样的道理,如果 需要 添加sqlserver的数据源,同样的方式 添加一个sqlserver的服务就可以加以注入

  • 相关阅读:
    Java设计模式-状态模式(State)
    Java设计模式-备忘录模式(Memento)
    Java设计模式-命令模式(Command)
    Java设计模式-责任链模式(Chain of Responsibility)
    Java设计模式-迭代子模式(Iterator)
    Java设计模式-观察者模式(Observer)
    Java设计模式-模板方法模式(Template Method)
    Java设计模式-策略模式(strategy)
    Java设计模式-享元模式(Flyweight)
    Java设计模式-组合模式(Composite)
  • 原文地址:https://www.cnblogs.com/kinmos/p/7026081.html
Copyright © 2011-2022 走看看