• 单例模式最佳实践


    项目有个类需要使用单例模式,这我熟悉啊,眨眼之间就写了如下代码

    class A
    {
        protected static $instance = null;
    
        public static function getInstance()
        {
            if (is_null(self::$instance)) {
                self::$instance = new self();
            }
           
            return self::$instance;
        }
       
        //todo
    }
    

    写完了,可以回家了,不过凭我多年写代码第六感的直觉,我隐约觉得好像哪里不对,瞟了一眼老司机的代码,如下

    class A
    {
        protected static $instance = null;
    
        public static function getInstance()
        {
            if (is_null(self::$instance)) {
                self::$instance = new static();
            }
           
            return self::$instance;
        }
       
        public function say()
        {
            echo 'I am A'.PHP_EOL;
        }
    }
    

    看似一样,实则暗藏玄机,关键就在new static(),你可能会说这个我知道,后期静态绑定,如果你这么认为,那么我只能说,恭喜你,答对了。如果你不知道这是啥,没关系,请看这里
    可是why要这么写呢,我脑海中出现了柯南后脑勺的那道闪电,继承。看下面代码

    class A
        {
            protected static $instance = null;
        
            public static function getInstance()
            {
                if (is_null(self::$instance)) {
                    self::$instance = new self();
                }
               
                return self::$instance;
            }
           
            public function say()
            {
                echo 'I am A'.PHP_EOL;
            }
        }
       
        class B extends A
        {
            public function say()
            {
                echo 'I am B'.PHP_EOL;
            }
            
            public function test()
            {
                echo 'B test'.PHP_EOL;
            }
            
        }
       
       $b = B::getInstance(); //$b是类A的实例
       $b->test();
    

    运行结果

    PHP Fatal error:  Uncaught Error: Call to undefined method A::test()
    

    $b是类A的实例,但是我们需要类B的实例,使用new static()的话,B::getInstance()得到类B的实例,这对应后期静态绑定的非转发调用(non-forwarding call)

    在tp和laravel框架中,Container类是这样实现的单例,这种写法我觉得从语义上更清晰一些,但是功能上是一样的。

    **
    * Set the globally available instance of the container.
    *
    * @return static
    */
    public static function getInstance()
    {
        if (is_null(static::$instance)) {
            static::$instance = new static;
        }
    
        return static::$instance;
    }
    
  • 相关阅读:
    最小区间问题
    vscode auto import npm package All In One
    韩国梨泰院踩踏事件中的物理知识 All In One
    Next.js dynamic router All In One
    Headless UI All In One
    cnblogs 标签数量上限 bug All In One
    nvm & grep filter out only Node.js Latest LTS versions All In One
    PB取datawindow生成的语句。要在datawindow的sqlpreview事件
    通达OA数据库服务断电无法启动的处理方法(亲测20201007。通达OA2017版本)
    pb里面如何提取截取字符串的前几位
  • 原文地址:https://www.cnblogs.com/whyly/p/13717178.html
Copyright © 2020-2023  润新知