前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式第一讲(单例模式)

设计模式第一讲(单例模式)

作者头像
Mandy的名字被占用了
发布2019-11-12 13:31:15
3890
发布2019-11-12 13:31:15
举报
文章被收录于专栏:菜鸟成长学习笔记

文章导读

大家好,我是卡二条,很感谢大家关注我的个人微信公众号.为什么写这篇文章呢?主要是因为最近在公司负责架构这一块所遇到的一些问题,所感想而来。

到今天加入现在的团队也整整3个月了,一直负责架构这一块的工作内容,从最开始接手项目,可谓是十分糟糕,之前的项目经常出现数据不一致,扩展性差,异常不易排查等情况.在重构的过程中,将自己所学到的设计模式大量用到项目中,保证了项目后期的正常运行,同时也保证了项目的高可用、高扩展.于是便想着将自己了解到的设计模式通过文章的方式写出来,尽可能的保证每天分享一个设计模式,希望对大家有所帮助.如文章有什么不合适的地方,往大家指正.

分享的内容主要是以PHP代码作为演示代码,或许有时会参考其他的编程语言.分享的几点,主要是围绕以下几点.

  • 设计模式的定义
  • 设计模式的利与弊
  • 设计模式的代码演示
  • 设计模式的使用场景

其实个人最看中的是使用场景,很多的文章或者很多的书籍都只是单纯的讲理论知识,讲设计模式的好处等等,却缺乏对使用场景的分析,导致学习后不能很快的掌握.

单例模式的定义

作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。简而言之,就是去new 一个类的时候,不是每new 一次就创建一个对象,而是每次new 都是使用的同一个对象.可以查看下面的var_dump()函数打印的内容.

单例模式的三个要素

1.保存类唯一实例的静态变量.

2.构造函数和克隆函数必须是私有的,防止外部去实例化,这样就不存在单例模式的意义.

3.提供一个可供外部访问的公共静态方法,这个方法返回该类的唯一实例.

单例模式的优点

在PHP中的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 在使用面向对象的方式开发时, 如果使用单例模式, 则可以避免大量的 new 操作消耗的资源。而不完全是对系统资源的节省, 可以避免重复实例化,因为 PHP 每次实例化一个类之后都会清理掉对应的资源,当再次使用的时候又会在重新去实例化一次。

单例模式演示

  • 不使用单例模式
代码语言:javascript
复制
class Single {
    public function index() {        return '';    }}
$single1 = new Single();$single2 = new Single();var_dump($single1);var_dump($single2);
if ($single2 === $single1) {    echo "是同一个对象";} else {    echo "不是同一个对象";}

打印结果

代码语言:javascript
复制
object(Single)#1 (0) {}object(Single)#2 (0) {}不是同一个对象
  • 上面对象打印的#1,#2就是对象的序号.这就表明两个对象是不同的对象,同时对这两个对象做比较,===是全等于,要求数据类型,值相等.由于这两个变量只是类型相等(都是对象),但是值不想等,也就是说在内容中不属于同一片空间.因此便不属于同一个对象.
  • 使用单例模式
代码语言:javascript
复制
class Single2 {    // 1.声明一个静态属性,用户保存类的实例    public static $instance;    //3. 将构函数私有化,避免外部new(每new一次,就不是同一个实例)    private function __construct() {    }    // 2.声明一个静态的公共方法,用户外部调用本类的实例    public static function getInstance() {        if (!(self::$instance instanceof self)) {            self::$instance = new self;        }        return self::$instance;    }    //3. 克隆函数私有化,避免外部clone(每clone一次,就不是同一个实例)    private function __clone() {
    }}$singleDemo1 = Single2::getInstance();$singleDemo2 = Single2::getInstance();
var_dump($singleDemo1->getInstance());var_dump($singleDemo2->getInstance());if ($singleDemo1 === $singleDemo2) {    echo "是同一个对象";} else {    echo "不是同一个对象";}

打印结果

代码语言:javascript
复制
object(Single2)#3 (0) {}object(Single2)#3 (0) {}是同一个对象
  • 上面的两个#3都是属于不同的变量,但却是同一个对象.为什么是3,是上一个实例中,实例化了两次,因此这里就变成了3.

图例演示

(未使用单例模式,每次实例化类)

(使用单例模式,每次实例化类)

单例模式使用的场景

1.数据库连接,减少对数据库的 new 操作,从而减少内存资源和系统资源的消耗。

2.配置资源的共享,在一个系统中,配置资源都是全局的,使用单例模式也可以减少每次去读取配置带来的内存和系统资源的消耗。

在公司项目中用的是ThinkPHP框架,大量操作Redis,日志缓存的业务场景.这些都是我们自定义的类来操作,是因为ThinkPHP框架中操作Redis的可用函数过少,便考虑自行封装Redis操作类.同时,日志操作我们使用了Monolog(https://github.com/Seldaek/monolog)来处理日志,这些都属于自行封装的扩展.为了避免每次new 都会实例化一个对象,便在封装每一个扩展时,都使用到了单例模式.

总结

由于单例模式非常简单,今天通过代码分享,是为了分析单例模式其中的原理.由于文章会不断的更新,都会发布在个人的博客中,以后每一篇文章都可以点击阅读原文按钮进行查看最新内容.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 卡二条的技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章导读
  • 单例模式的定义
  • 单例模式的三个要素
  • 单例模式的优点
  • 单例模式演示
  • 图例演示
  • 单例模式使用的场景
  • 总结
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档