道者编程


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

一:构造注入:

<?php
class Main
{
    public $name;
    //构造注入
    public function __construct($str)
    {
        $this->name = $str;
    }
    public function Method()
    {
        $this->name->Method();
    }
}
 
class A
{
    public function Method()
    {
        echo '我是A';
    }
}
class B
{
    public function Method()
    {
        echo '我是B';
    }
}
 
$a=new Main(new A()); //注入A类
$a->Method();

Main类依赖A类,通过构造器传入参数,一旦A类参数发生修改,Main类不需要改动,只需修改调用的地方,因为A类的创建在外部,这样Main类就无需关心A类。

二:工厂模式

<?php
interface Getdata
{
    public function Method();
}

class A implements Getdata
{
    public function Method()
    {
        echo "我是A";
    }
}

class B implements Getdata
{
    public function Method()
    {
        echo "我是B";
    }
}

class Factory
{
    public static function bind($transport)
    {
        
        switch ($transport) {
            case 'A':
                return new A();
                break;

            case 'B':
                return new B();
                break;
        }
    }
}

$getdata = Factory::bind('A'); // 加载A类
$getdata -> Method();

进一步解耦出来,这里AB类参数需要改动,只需要改动Factory类,Main可以设置切换不同的类,这种模式很常见,比如缓存,自由切换memcache,redis,db等,都可以用这种模式切换。这种需要一一对应,各类的实例化在工厂中完成,各类的方法结构必须统一,如果需求增加,工厂也会变的更庞大。

三:IOC容器

依赖注入:从应用程序的角度描述,可以把依赖注入,即:应用程序依赖容器创建并注入它所需要的外部资源;只要不是由内部生产(比如初始化、构造函数 __construct 中通过工厂方法、自行手动 new 的),而是由外部以参数或其他形式注入的,都属于依赖注入

控制反转:从容器的角度描述,即:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。

两者从不同角度解释,一句话和工厂模式的区别:高层模块不应该依赖于低层模块,二者都应该依赖于抽象,这样各层之间解耦。

1:simple di container的容器代码

<?php
class A
{
    public function Method()
    {
        echo "我是A";
    }
}

// simple di container的容器代码
// 该代码使用了后期静态绑定
class IoC
{
  protected static $registry = [];
    
  public static function bind($name, Callable $resolver)
    { 
      static::$registry[$name] = $resolver; 
    }
    public static function make($name)
      {
        if (isset(static::$registry[$name])) {
          $resolver = static::$registry[$name];
            return $resolver(); //必须加()
        }
        throw new Exception('Alias does not exist in the IoC registry.'); //Ioc中没有别名
      }
}
    
IoC::bind('a', function () {
  return new A();

}); //这里只是先注册进去,不执行。

$a = Ioc::make('a'); //从容器取得A
$a->Method(); //执行方法

PHP后期绑定:http://php.net/manual/zh/language.oop5.late-static-bindings.php

2:Twittee容器代码,该代码使用了魔术方法

<?php
class A
{
    public function Method()
    {
        echo "我是A";
    }
}

//Twittee容器代码
class Container
{
	private $s = array();
	
	function __set($k, $c) //注册
	{
		$this->s[$k] = $c;
	}
    
	function __get($k) //获取
    {
		return $this->s[$k]($this);
	}
 }

$Ioc = new Container();
    
$Ioc->A = function () {
	return new A();
};

$Ioc->A->Method();


最新评论:
1楼 广东省深圳市 电信 发表于 2018-09-25 15:29:21
666666
2楼 北京市 (静安中心机房) 发表于 2018-09-26 17:21:02
陈总NO.1
共有 2 条记录  首页 上一页 下一页 尾页 1
我要评论:

看不清楚


链接