欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

5.28容器注入(IOC)和门面模式(facade)

程序员文章站 2022-03-03 19:21:07
...
  • 容器:也称服务容器,简称(IOC),

  • 基本思想:就是拿来就用,最大限度的简化外部对象的调用,类似于:[即插即用]的思想。

  • 简单的讲就是将工具类打包成一个容器,在客户端完成工具类的实例化为对象,再以参数的方式直接传递给工作类的方法

  • 基本实现分三步:

        首先是工具类

        //数据库操作类
        class Db
        {
           //数据库连接
           public function connect()
           {
              return '数据库连接成功<br>';
           }
        }
        
        //数据验证类
        class Validate
        {
           //数据验证
           public function check()
           {
              return '数据验证成功<br>';
           }
        }
        
        //视图图
        class View
        {
           //内容输出
           public function display()
           {
              return '用户登录成功';
           }
        }


    1.创建容器,将类与类的实例化过程绑定到容器中(不局限于类,也可是接口或其它)

    //一.创建容器类        
        class Container
        {
           //创建属性,用空数组初始化,该属性用来保存类与类的实例化方法
           protected $instance = [];
        
           //初始化实例数组,将需要实例化的类,与实例化的方法进行绑定
           public function bind($abstract, Closure $process)
           {
              //键名为类名,值为实例化的方法
              $this->instance[$abstract] = $process;
           }
        
           //创建类实例
           public function make($abstract, $params=[])
           {
              return call_user_func_array($this->instance[$abstract],[]);
           }
        
        }

2.服务注册,将可能用到的工具类全部绑定到容器中

//二、服务绑定: 将类实例注册到容器中        
        $container = new Container(); 
        
        //将Db类绑定到容器中
        $container->bind('db', function(){
           return new Db();
        });
        
        //将Validate类实例绑定到容器中
        $container->bind('validate', function(){
           return new Validate();
        });
        
        //将View类实例绑定到容器中
        $container->bind('view', function(){
           return new View();
        });
        
        //测试:查看一下当前容器中的类实例
        // var_dump($container->instance); die;

3.容器依赖:或者叫依赖容器,调用工作类时直接传入容器对象即可,工具类的实例化由容器完成

//三、容器依赖:将容器对象,以参数的方式注入到当前工作类中        
        
        //用户类:工作类
        class User
        {
           //创建三个成员属性,用来保存本类所依赖的对象
           // protected $db = null;
           // protected $validate = null;
           // protected $view = '';
           //这三个与外部对象对应的三个属性可以全部删除了,因为它们都已经事先注册到了容器中
        
           //用户登录操作
           // public function login(Db $db, Validate $validate, View $view)
           //此时,只需从外部注入一个容器对象即可,Db,Validate和View实例方法全部封装到了容器中
           public function login(Container $container)
           {
              //实例化Db类并调用connect()连接数据库
              // $db = new Db();
              // echo $db->connect();
              echo $container->make('db')->connect();
        
              //实例化Validate类并调用check()进行数据验证
              // $validate = new Validate();
              // echo $validate->check();
              echo $container->make('validate')->check();
        
              //实例化视图类并调用display()显示运行结果
              // $view = new View();
              echo $container->make('view')->display();
           }
        }
        //在客户端完成工具类的实例化(即工具类实例化前移)
        // $db = new Db();
        // $validate = new Validate();
        // $view = new View();
        
        //现在注入过程就非常简单了,只需要从外部注入一个容器对象即可
        
        //创建User类
        $user = new User();
        
        //调用User对象的login方法进行登录操作
        // echo $user->login();
        // 将该类依赖的外部对象以参数方式注入到当前方法中,当然,推荐以构造器方式注入最方便
        echo '<h3>用依赖容器进行解藕:</h3>';
        // echo $user->login($db, $validate, $view);
        //现在工作类中的login方法不需要再像对象依赖注入那样写三个对象了,只需要一个容器对象就可以了
        echo $user->login($container);
  • 外观模式:facade,也叫门面模式 也叫静态代理
    1.用一句来说:就是将操作进行封装,对外提供一个统一的接口(使用了facade类  当你调用类中的方法时,不在考虑该方法是否为静态,统统使用静态方式调用即可)


  • require 'container.php';
    
    //创建Facade类,实现以上三个功能
    class Facade
    {
       //连接数据库
       public static function connect(Container $container)
       {
          return $container->make('db')->connect();
       }
    
       //用户数据验证
       public static function check(Container $container)
       {
          return $container->make('validate')->check();
       }
    
       //输出提示信息
       public static function display(Container $container)
       {
          return $container->make('view')->display();
       }
    }
    
    //客户端调用
    echo Facade::connect($container);
    echo Facade::check($container);
    echo Facade::display($container);
  • 可以在外观模型中使用初始化方法事先注入容器对象,来简化客户端调用
  • require 'container.php';
    
    
    class Facade
    {
       //创建成员属性保存容器对象
       protected static $container = null;
    
       //创建初始化方法为容器对象赋值
       public static function initialize(Container $container)
       {
          static::$container = $container;
       }
       //连接数据库
       public static function connect()
       {
          return static::$container->make('db')->connect();
       }
    
       //用户数据验证
       public static function check()
       {
          return static::$container->make('validate')->check();
       }
    
       //输出提示信息
       public static function display()
       {
          return static::$container->make('view')->display();
       }
    }
  • //客户端调用
    
    //初始化类门面类中的容器对象
    Facade::initialize($container);
    
    //静态统一调用内部的方法(无须重复注入依赖容器对象啦,实现了细节隐藏,通用性更强)
    echo Facade::connect();
    echo Facade::check();
    echo Facade::display();