容器与外观模式学习总结

原创 2018-12-03 14:53:28 322
摘要:容器(Container),实现类的统一管理,确保对象实例的唯一性。要解决的问题:在一个类中 实例化另外一个类, 就是依赖性强, 耦合度高, 除了可使用 依赖注入(Dependency Injection) 来解耦之外,还可以进一步使用 依赖容器 container 来解耦,容器就是一个装有各种类的对象的仓库, 然后通过 依赖容器 来实现对象的调用最后还可以使用 facade 封装各个类(对象)

容器(Container),实现类的统一管理,确保对象实例的唯一性。

要解决的问题:在一个类中 实例化另外一个类, 就是依赖性强, 耦合度高, 除了可使用 依赖注入(Dependency Injection) 来解耦之外,还可以进一步使用 依赖容器 container 来解耦,容器就是一个装有各种类的对象的仓库, 然后通过 依赖容器 来实现对象的调用

最后还可以使用 facade 封装各个类(对象) 的方法, 形成对外的统一方法, 从而使用者(开发者) 无需关心调用的是哪个类的哪个方法, ( 而统一使用的是 facade 类的方法)

<?php 
// 学生类 Student.php
class Student
{
    public function info()    
    {
        echo '<br>我是学生<br>';
    }
}
<?php 
//教师类 Teacher.php
class Teacher
{
    public function info()    
    {
        echo '我是老师<br>';
    }
}
<?php 
include 'Teacher.php';
include 'Student.php';
 
//一.创建容器类  Container.php
/**
 * 容器,也称服务容器,简称(IOC)
 * 基本实现分三步:
 * 1.创建容器,将类与类的实例化过程绑定到容器中(不局限于类,也可是接口或其它)
 * 2.服务注册,将可能用到的工具类全部绑定到容器中
 * 3.容器依赖:或者叫依赖容器,调用工作类时直接传入容器对象即可,工具类的实例化由容器完成
 */
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(); 

//将Student类绑定到容器中
$container->bind('student', function(){
    return new Student();
});

//将Teacher类实例绑定到容器中
$container->bind('teacher', function(){
    return new Teacher();
});

//测试:查看一下当前容器中的类实例
var_dump($container->instance);
// 执行结果如下:
// array(2) {
//   ["student"]=>
//   object(Closure)#2 (0) {
//   }
//   ["teacher"]=>
//   object(Closure)#3 (0) {
//   }
// }


// 门面(Facade)为容器(Container)中的类提供了一个静态调用接口,相比于传统的静态方法调用, 带来了更好的可测试性和扩展性,你可以为任何的非静态类库定义一个facade类。

class Facade
{
    //创建成员属性保存容器对象
    protected static $container = null;

    //创建初始化方法为容器对象赋值
    public static function initialize(Container $container)
    {
        static::$container = $container;
    }

    /**
     * 因为已经在初始化方法中将容器对象导入到了当前类中,
     * 并且保存到了类的静态属性中,为所有类成员所共享,
     * 所以以下方法可直接调用不用再容器注入
     * 注意:这里全部采用后期静态延迟绑定方法来访问当前容器对象
     * 这主要是为了方便用户在静态继承的上下文环境中进行调用
     */
    
    //查询学生
    public static function info(Container $container)
    {
        return $container->make('student')->info();
    }

    //查询教师
    public static function info2(Container $container)
    {
        return $container->make('teacher')->info();
    }
}

//客户端调用
//初始化类门面类中的容器对象
Facade::initialize($container);

//静态统一调用内部的方法
echo Facade::info($container);
echo Facade::info2($container);


批改老师:天蓬老师批改时间:2018-12-03 14:58:59
老师总结:保证唯一性是单例模式, 门面技术本质上,是实现了项目依赖的统一管理

发布手记

热门词条