博主信息
博文 71
粉丝 1
评论 1
访问量 102135
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
528-ThinkPHP5.1之容器注入(IOC)和门面模式(facade)
小威的博客
原创
3049人浏览过
  • 容器注入:也叫 依赖注入容器,

用户在客户端使用容器来进行类管理,还可以将类的实例(对象)做为参数,传递给类方法,自动触发依赖注入。

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

  • 容器:也称服务容器,简称(IOC)类似于:[即插即用]的工具,最大限度的简化外部对象的调用

  • 实现步骤有三步:

创建工具类

//数据库操作类
class Db
{
	//数据库连接
	public function connect()
	{
		return '数据库连接成功<br>';
	}
}

//数据验证类
class Validate
{
	//数据验证
	public function check()
	{
		return '数据验证成功<br>';
	}
}

//视图
class View
{
	//内容输出
	public function display()
	{
		return '用户登录成功';
	}
}

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

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],[]);
	}
}

二、服务绑定:将可能用到的工具类全部绑定到容器中

      服务注册:将类实例注册到容器中

$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();
});

三、容器依赖:将容器对象,以参数的方式注入到当前工作类中

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

//用户类:工作类
class User
{
	//用户登录操作
	// public function login(Db $db, Validate $validate, View $view)
	//此时,只需从外部注入一个容器对象即可,Db,Validate和View实例方法全部封装到了容器中
	public function login(Container $container)
	{
		//实例化Db类并调用connect()连接数据库
		echo $container->make('db')->connect();

		//实例化Validate类并调用check()进行数据验证
		echo $container->make('validate')->check();

		//实例化视图类并调用display()显示运行结果
		echo $container->make('view')->display();
	}
}

客户端调用

//创建User类
$user = new User();

//调用User对象的login方法进行登录操作
//将该类依赖的外部对象以参数方式注入到当前方法中,推荐以构造器方式注入
echo '<h3>用依赖容器进行解藕:</h3>';
//工作类中的login方法不需要写三个对象了,只需要一个容器对象即可
echo $user->login($container);

下面案例使用依赖注入的思路是APP用到A类,A类需要B类,B类需要C类。那么先创建C类,再创建B类并把C注入,再创建A类,并把B类注入,再调用A方法,A调用B方法,接着做些其它工作。

<?php

class C
{
    public function doSomething()
    {
        echo __METHOD__, '我是C类|';
    }
}

class B
{
    private $c;

    public function __construct(C $c)
    {
        $this->c = $c;
    }

    public function doSomething()
    {
        $this->c->doSomething();
        echo __METHOD__, '我是B类|';
    }
}
class A
{
    private $b;

    public function __construct(B $b)
    {
        $this->b = $b;
    }

    public function doSomething()
    {
        $this->b->doSomething();
        echo __METHOD__, '我是A类|';;
    }
}

class Container
{
    private $s = array();

    function __set($k, $c)
    {
        $this->s[$k] = $c;
    }

    function __get($k)
    {
        return $this->s[$k]($this);
    }
}

$class = new Container();

$class->c = function () {
    return new C();
};
$class->b = function ($class) {
    return new B($class->c);
};
$class->a = function ($class) {
    return new A($class->b);
};


// 从容器中取得A
$foo = $class->a;
$foo->doSomething(); // C::doSomething我是C类|B::doSomething我是B类|A::doSomething我是A类|


  • 门面模式(facade) 也叫 外观模式   就是将操作进行封装,对外提供一个统一的接口

门面为容器中的类提供了一个静态调用接口,相比于传统的静态方法调用, 带来了更好的可测试性和扩展性,你可以为任何的非静态类库定义一个 facade 类。类似于一个导航网站,将多个网站,放在一个页面中,方便用户快速浏览各类网站。。

<?php 

//数据库操作类
class Db
{
	//数据库连接
	public function connect()
	{
		return '数据库连接成功<br>';
	}
}

//数据验证类
class Validate
{
	//数据验证
	public function check()
	{
		return '数据验证成功<br>';
	}
}

//视图
class View
{
	//内容输出
	public function display()
	{
		return '用户登录成功';
	}
}

//一、创建容器类
class Container
{
	//创建属性,用空数组初始化,该属性用来保存类与类的实例化方法
	public $instance = [];

	//初始化实例数组,将需要实例化的类,与实例化的方法进行绑定
	public function bind($abstract, Closure $process)
	{
		//键名为类名,值为实例化的方法
		$this->instance[$abstract] = $process;
	}

	//创建类实例
	public function make($abstract, $params=[])
	{
		return call_user_func_array($this->instance[$abstract],[]);
	}
}

//二、服务绑定: 将类实例注册到容器中
$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();
});

//三、容器依赖:将容器对象,以参数的方式注入到当前工作类中
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();

第三步可以单独调用

批改状态:未批改

老师批语:
本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!
全部评论 文明上网理性发言,请遵守新闻评论服务协议
0条评论
作者最新博文
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号

  • 登录PHP中文网,和优秀的人一起学习!
    全站2000+教程免费学