单例模式

模式定义

单例模式确保一个类只有一个实例,并提供一个全局访问点。当现实中只需要一个对象,或者为了节省系统资源,又或者是为了共享数据的时候可以使用单例模式。

代码实现

我们先来看看单例模式的标准实现:

final class Singleton
{
/**
* @var Singleton
* 维持一个对自身的引用,并保证其唯一性
*/
private static $instance; // 获取实例唯一的入口
public static function getInstance(): Singleton
{
if (null === static::$instance) {
static::$instance = new static();
} return static::$instance;
} // 不允许通过new的方式产生,只能通过Singleton::getInstance()方法
private function __construct()
{
} // 也不允许clone()方法,此方法也会产生一个新的实例
private function __clone()
{
} // 也不允许反序列化,因为反序列化也会产生一个新的实例
private function __wakeup()
{
}
}

  

 

单例模式不允许产生单例的类被继承,不允许通过new方式产生,除了规定的getInstance()方法,别的实例化的途径基本被堵死。而在类的内部维持一个对自身的引用,并保证其是唯一的。

单例模式估计是所有涉及模式中最简单的了,在PHP和Yii中很少见到直接这么使用的,更多的是其变化的形式。

Yii的单例模式

Yii使用单例的场景非常多,比如请求开始创建的Application,Yii,Request,Response等对象功能都十分丰富且开销也很大,维持一个单例就可供请求的整个生命周期使用。在请求开始即创建,请求结束自行销毁,中间不销毁也不创建。这些对象使用了单例没有疑问,但是这些单例的产生、管理和使用却是有不同讲究的。

对象如何创建又如何维护,恐怕任何一个PHP框架都绕不开这个问题。Yii2采用服务定位器和依赖注入容器来提供大部分对象。在容器中使用单例好处是非常明显的。至少可以表现在节省内存和公用组件方面。

节省内存

Yii::$container 在内存中仅有一份,所有使用DI容器的场合(Application/Module等)都用到这个DI容器。 这就节省了大量的内存空间和反复构造实例的时间。

共用组件

更为重要的是,DI容器的单例化,使得Yii不同的模块共用组件成为可能。 可以想像,由于共用了DI容器,容器里面的内容也是共享的。因此,你可以在A模块中改变某个组件的状态,而B模块中可以了解到这一状态变化。 但是,如果不采用单例模式,而是每个模块(Application/Module)都维护一个自己的DI容器, 要实现这一点难度会大得多。所以,这种共享DI容器的设计是必然的、合理的。

应用举例

在 Yii.php 中:

只在入口脚本require '../Yii.php'时创建一个Container实例 Yii::$container = new yii\di\Container();

在Yii框架中,除了少数情况,都是通过Yii::createObject()来创建类的实例

而在Yii::createObject()中始终用到一个单例Yii::$container

最新文章

  1. [异常解决] windows用SSH和linux同步文件&linux开启SSH&ssh client 报 algorithm negotiation failed的解决方法之一
  2. HTML、CSS、JS在前端开发中都扮演怎样的角色
  3. Servlet目录
  4. InstallShield 2010 使用 .net framework 4.5
  5. 【转载】Android内存泄露
  6. atitit.eclipse 新特性总结3.1--4.3
  7. Digital Image Processing 学习笔记3
  8. android之datepicker控件用法
  9. 将List<T>转化成 DataTable--调整可空类型的转化错误
  10. 导入MyEclipse项目乱码
  11. 忘记gitlab的root密码
  12. openScales源码学习系列之 Feature属性
  13. HDU------checksum
  14. Java历程-初学篇 Day04选择结构(1)
  15. css中设置div水平居中,margin:0px auto无用的情况
  16. hdu2089 不要62--经典数位DP
  17. Python开发【第二篇】运算符
  18. VS2010 开发 VB6.0 activeX控件 dll
  19. 利用MySQL游标进行计算排名
  20. Linux下图形数据库Neo4j单机安装

热门文章

  1. TCP和UDP并实现socket的简单通信
  2. SCHED_FIFO与SCHED_OTHER调度机制
  3. 咏南中间件D7客户端演示
  4. [Java]在JAVA中使用Oracle的INSERT ALL语法进行批量插入
  5. Nginx设置黑名单
  6. 自定义控件之Region区域
  7. 【转载】 一文看懂深度学习新王者「AutoML」:是什么、怎么用、未来如何发展?
  8. 学成在线_nginx遇到的问题
  9. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_12-用户退出-服务端
  10. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_03-用户认证-认证服务查询数据库-查询用户接口-接口定义