微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

phalapi-进阶篇2(DI依赖注入和单例模式)

#phalapi-进阶篇2(DI依赖注入和单例模式)#

##前言## 在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架.

离上一次更新过去了快两周,在其中编写了一个关于DB分表分库解决大数据量的拓展,有兴趣的童鞋可以了解了解.废话不多说,本小节在于解释一下在PhalApi框架中两个比较好的思想,单例模式和依赖注入.

附上:

官网地址:http://www.phalapi.net/

开源中国Git地址:http://git.oschina.net/dogstar/PhalApi/tree/release

##1. 单例模式##

单例模式对于长期进行过面向对象编程的童鞋应该不算陌生,在学习PHP的童鞋也应该有听过,这里简单的聊一聊单例模式到底是一个怎么样东西,解决了什么问题,并且在PhalApi中是如何实现的.

单例单例,所谓单例也就是有且只有一个存在,这就是单例,不难看出他的好处资源利用少因为只有一个,大家都是知道要使用一个类必须要实例他也就是new在每次new一个对象的时候都会在内存中生成一块区域来存放这个实例,如果在程序一次运行中使用了很多的new实例化了同一个对象,那就比较消耗资源了,但是如果是通用一个使用全局变量global程序又会显得不优雅而且会很乱,在这种情况下单例模式就产生了.

单例模式就是一个两全其美的一个方法既可以全局通用,二不用担心占用过多的资源,三又非常优雅,我们来一起看看在PhalApi中是如何实现单例模式的:

//大家看到我们常用的DI方法内部实现的是PhalApi_DI中的静态方法one方法
function DI() {
    return PhalApi_DI::one();
}

然后我们看向one方法内部

每当我们请求过来的时候先验证静态变量instance是不是没有被初始化,如果是第一次调用他会在内部去实例化PhalApi_DI类然后负值给**$instance**然后返回实例好的这个静态变量,当我们下次在请求过来的时候这个静态变量已经被实例化好了就会直接跳过实例的过程直接返回这个对象,也就是我们在PhalApi框架所有的地方使用的DI方法其实都是一个对象,在内存中只存在一块区域,代码如下:

public static function one(){
    if(self::$instance == NULL){
        self::$instance = new PhalApi_DI();
        self::$instance->onConstruct();
    }

    return self::$instance;
}

其实不难我们只用吧new一个类的操作封装到我们需要new的类的静态方法在向上面一样的去判断,就可以很简单的去实现单例模式.

##2. 依赖注入##

依赖注入又称之为**"控制反转",如果是熟悉javaweb开发的spring**框架应该有比较深的感触,在这里也不往深的讲,就简单讲解一下PhalApi中DI依赖注入的实现让大家了解这种设计模式如何实现以及自此基础上实现的惰性加载机制.

###2.1 DI依赖注入实现###

大家在PhalApi中常用的DI()方法,也就是采用我们上面所谓的单例模式不用多说了,也就是我们每次使用DI()其实就是在使用PhalApi_DI类,那么我们依赖注入的关键也就是在PhalApi_DI之中

先来讲一下他的一个实现方式在来讲具体实现,这里举个例子:

//配置
DI()->config = new PhalApi_Config_File(API_ROOT . '/Config');

其实在内部有一个数组,它吧config作为了key,吧new PhalApi_Config_File(API_ROOT . '/Config')作为了value然后保存了起来当我们下一次使用DI->config->get();的时候它就会根据key值config拿出开始new好的类,所以可以说config操作是依赖于DI(),而且在使用DI()->config的时候永远都是在使用的一个实例,也能减少资源的消耗.

有的童鞋就好奇了为什么DI()->config会存到数组需要的时候会拿出来呢,感兴趣的童鞋可以百度一下魔法方法**__ser和__get**

/**大家可以看到这是PhalApi_DI中的魔法方法__set
 * 也就是当使用DI()->config = new PhalApi_Config_File(API_ROOT . '/Config');的时候
 * 获得的name值就是config,获得的value也就是new PhalApi_Config_File(API_ROOT . '/Config');
 */get同理,在内部实现都是调用了内部get和set方法
public function __set($name,$value){
    $this->set($name,$value);
}

public function __get($name){
    return $this->get($name,NULL);
}

看完之后大家是不是觉得很简单啊,大家以后也可以在自己设计类的时候采用这种灵活的魔法方法实现.

###2.2 惰性加载###

在PhalApi中的DI()方法也提供惰性加载,惰性加载如字意也就是当类没有被使用到的时候不会加载,这样的操作也是为了避免浪费不必要的资源,当我们不是用的时候永远不会去实例化只有当你使用到的时候才会去new这个类然后实例化之后使用,我们来看看是如何实现的.

//当我们执行以下语句的时候,在依赖注入的时候存的是value值是字符串的test
DI()->test = 'test';

//使用DI()->test->test();的时候会使用到PhalApi中的get方法,在get方法中有一段代码
$this->data[$key] = $this->initService($this->data[$key]);

//在initService方法内部验证了value是字符串就实例化了再返回

if($config instanceOf Closure){
    $rs = $config();
}elseif(is_string($config) && class_exists($config)){
    $rs = new $config();
    if(is_callable(array($rs,'onInitialize'))){
        call_user_func(array($rs,'onInitialize'));
    }
}else{
    $rs = $config;
}

##3. 总结##

在本节中简单的讲解了关于单例模式,依赖注入以及惰性加载,这几种设计模式都是常用的能后减少资源利用率的有效的方法,希望大家看了这篇介绍能够实地的去体验一下PhalApi中的这几种模式,在下一小节就讲解如何构建自己的拦截器,希望大家能够持续关注!

注:笔者能力有限有说的不对的地方希望大家能够指出,也希望多多交流!

官网QQ交流群:421032344 欢迎大家的加入!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图:提供一种方法顺序访问一个聚合对象中的每个元素,而又不想暴露该对象的内部表示。应用:STL标准库迭代器实现、Java集合类型迭代器等模式结构:心得:迭代器模式的目的是在不获知集合对象内部细节的同时能对集合元素进行遍历操作
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种:(1)同步阻塞IO(BlockingIO):即传统的IO模型。(2)同步非阻塞IO(Non-blockingIO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的N
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定义一系列算法,把他们封装起来,并且使他们可以相互替换,使算法可以独立于使用它的客户而变化。应用:排序的比较方法、封装针对类的不同的算法、消除条件判断、寄存器分配算法等。模式结构:心得:对对象(Context)的处理操作可
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个作用于某对象结构中的各元素的操作,它使你在不改变各元素的类的前提下定义作用于这些元素的新操作。应用:作用于编译器语法树的语义分析算法。模式结构:心得:访问者模式是要解决对对象添加新的操作和功能时候,如何尽可能不修改对象的类的一种方
命令模式(Command)命令模式(Command)[Action/Transaction]意图:将一个请求封装为一个对象,从而可用不同的请求对客户参数化。对请求排队或记录请求日志,以及支持可撤消的操作。应用:用户操作日志、撤销恢复操作。模式结构:心得:命令对象的抽象接口(Command)提供的两个
生成器模式(Builder)生成器模式(Builder)意图:将一个对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。 应用:编译器词法分析器指导生成抽象语法树、构造迷宫等。模式结构:心得:和工厂模式不同的是,Builder模式需要详细的指导产品的生产。指导者(Director)使用C
设计模式学习心得《设计模式:可复用面向对象软件的基础》一书以更贴近读者思维的角度描述了GOF的23个设计模式。按照书中介绍的每个设计模式的内容,结合网上搜集的资料,我将对设计模式的学习心得总结出来。网络上关于设计模式的资料和文章汗牛充栋,有些文章对设计模式介绍生动形象。但是我相信“一千个读者,一千个
工厂方法模式(Factory Method)工厂方法模式(Factory Method)[Virtual Constructor]意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实力化延迟到子类。应用:多文档应用管理不同类型的文档。模式结构:心得:面对同一继承体系(Produc
单例模式(Singleton)单例模式(Singleton)意图:保证一个类只有一个实例,并提供一个访问它的全局访问点。应用:Session或者控件的唯一示例等。模式结构:心得:单例模式应该是设计模式中最简单的结构了,它的目的很简单,就是保证自身的实例只有一份。实现这种目的的方式有很多,在Java中
装饰者模式(Decorator)装饰者模式(Decorator)[Wrapper]意图:动态的给一个对象添加一些额外的职责,就增加功能来说,比生成子类更为灵活。应用:给GUI组件添加功能等。模式结构:心得:装饰器(Decorator)和被装饰的对象(ConcreteComponent)拥有统一的接口