zoukankan      html  css  js  c++  java
  • 单例模式最佳实践

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

    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;
    }
    
  • 相关阅读:
    9.11练习:文件访问,写一个逐页显示文本文件的程序,提示输入一个文件名,每次显示文本文件的25行,暂停并向用户提示“按任意键继续”,按键后继续执行。
    关于将缓冲器内容写入文件
    关于移动文件指针
    关于file.writelines换行符的添加
    石头剪子布游戏
    关于浅拷贝,深拷贝
    关于list.extend(iterable)
    vs2012编译openssl
    Sublime Text 3 安装及插件推荐
    bower--包管理工具
  • 原文地址:https://www.cnblogs.com/whyly/p/13717178.html
Copyright © 2011-2022 走看看