专栏首页Lemon黄PHP设计模式——单例模式

PHP设计模式——单例模式

点击上方“Lemon黄”关注我哦,不定期原创文,定期好技术文推广分享

确保一个类只有一个实例,并提供对其的全局访问入口。

如果你去一家诊所做检查,刚好诊所最近提供了免费药物。这个促销工作进展得非常顺利,前台人员的病人人数都超出他们的承受能力。每个人都很忙,以至于没有一个井井有条的等候室,这简直是一片混乱。接待员中的病人大量涌入后,安妮感到沮丧和压力,她走进诊所负责人的办公室,脱口而出:“我们需要组织病人,否则我们将不知所措”。

诊所的负责人召开会议,要求工作人员提出建议,然后他们想到了售票系统的想法。目的是使患者有条理的等候,以便减轻前台人员的人工登记工作。

让我们来看看我们能提供怎样的帮助。

在进行任何代码设计之前,我们需要了解诊所的状况和能力。该诊所只有一台物理打印机。

我们可以设计TicketPrinter类,类似于以下定义的类:

class TicketPrinter
{
    public $isPaperOut;
    public function __construct()
    {
        $this->isPaperOut = true;
    }
 
    public function printTicket()
    {
        if ($this->isPaperOut) {
            // 装在更多的纸张到打印机
            $this->loadMorePapers();
            $this->isPaperOut = false;
        } else {
            // 打印
            $this->minusPaper();
            echo 'print queue number';
        }
    }
}

每次执行打印作业时,printerTicket()方法都必须检查纸张的状态。如果纸张用完,它将自动加载更多纸张(假设有可能)。

看来我们也需要检查墨水的状态。因此,我们还要添加如下:

class TicketPrinter {
    public $isPaperOut;
    public $isInkOut;
    public function __construct()
    {
        $this->isPaperOut = true;
        $this->isInkOut = true;
    }
 
    public function printTicket()
    {
        if ($this->isPaperOut) {
            // 装在更多的纸张到打印机
            $this->loadMorePapers();
            $this->isPaperOut = false;
        } else if($this->isInkOut ) {
            // 添加墨水
            $this->loadMoreInk();
            $this->isInkOut = false;
        } else {
            // 打印
            $this->minusPaper();
            // 使用墨水
            $this->deductInk();
            echo 'print queue number';
        }
    }
}

看来我们有一个工作中的TicketPrinter,但在继续之前,让我们再次检查一下情况。由于诊所中只有一台物理打印机,因此如果我们偶然创建了两个TicketPrinter类实例,将会发生什么情况。因为他们使用的是同一台共享打印机,所以肯定会引起很大的问题。

您可能会争辩说,我们总是可以只创建另一个TicketPrinter实例,但是如何确保每个人都遵循它呢?因此,我建议在这种情况下使用Singleton(单例)模式。

我们来稍微修改下TicketPrinter类:

class TicketPrinter
{
    private static $uniqueInstance=null;
    public $isPaperOut;
    public $isInkOut;
    private function __construct()
    {
        $this->isPaperOut = true;
        $this->isInkOut   = true;
    }
 
    public static function getInstance()
    {
        if (self::$uniqueInstance==null) {
            self::$uniqueInstance = new TicketPrinter();
        }
        return self::$uniqueInstance;
    }
 
    public function printTicket()
    {
    }
}

由于TicketPrinter的构造函数(__construct())已变为私有,因此构造函数无法正常实例化它。为了获得TicketPrinter的实例,我们改为:

$ticketPrinter = TicketPrinter::getInstance();

如你所见。单例模式(Singleton Pattern)确保在整个系统的任何时候仅存在一个TicketPrinter实例。

本文分享自微信公众号 - Lemon黄(lemonhunag)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 关于XGBoost、GBDT、Lightgbm的17个问题

    9.lightgbm和xgboost有什么区别?他们的loss一样么?算法层面有什么区别?

    统计学家
  • R语言从入门到精通:Day13

    在前面两次的教程中,我们学习了方差分析和回归分析,它们都属于线性模型,即它们可以通过一系列连续型 和/或类别型预测变量来预测正态分布的响应变量。但在许多情况下,...

    用户6317549
  • 伸展树的特性及实现

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    于小勇
  • 原创系列 |「冒泡排序」提升为「快速排序」,都发生了什么?

    彻底弄明白常用的排序算法的基本思想,算法的时间和空间复杂度,以及如何选择这些排序算法,确定要解决的问题的最佳排序算法,我们先总结下冒泡排序和其改进后的快速排序这...

    double
  • 这是我的10分钟 js 入门笔记

    别问做算法和数据分析的,怎么还学js. 工作了需要啥都得学,还得快。这就是互联网,适者生存,劣者淘汰。

    double
  • 「React 基础」在 React 项目中使用 ES6,你需要了解这些

    随着前端发展越来越快,JavaScript 这门语言也在不断的更新,从2015年开始,几乎每年都有一个新版本。新语言借鉴了类似 C#,Java 这些高级语言的特...

    前端达人
  • 学文科的他发明堆排序,逆袭成为斯坦福终身教授!

    计算机先驱奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德(Robert W.Floyd)和威廉姆斯(J.Williams)在1964年共同发明了堆排序算法...

    double
  • IT兄弟连 HTML5教程 多媒体应用 HTML图像地图

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    ITXDL
  • 更好的数据胜过更高级的算法

    数据清理是每个人都要做的事情之一,但很少有人专门讨论这件事,原因很简单,这不是机器学习的“最性感”的部分。而且,没有什么可供挖掘的隐藏技巧和秘密。

    统计学家
  • 栈指针&& 帧指针详解

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    于小勇

扫码关注云+社区

领取腾讯云代金券