在类方法和类中保持静态实例之间是否存在差异?

时间:2013-02-04 13:39:02

标签: php singleton

使用单例模式时。将静态实例保存在类中并将其保存在返回实例的方法中是否有任何区别?

实施例: 在课堂上。

class cExampleA {
    static $mInstance;

    protected function __construct() {
        /* Protected so only the class can instantiate. */
    }

    static public function GetInstance() {
        return (is_object(self::$mInstance) ? self::$mInstance : self::$mInstance = new self());
    }
}

返回方法内部。

class cExampleB {
    protected function __construct() {
        /* Protected so only the class can instantiate. */
    }

    static public function GetInstance() {
        static $smInstance;
        return (is_object($smInstance) ? $smInstance : $smInstance = new self());
    }
}

另一方面,在示例中使用有效的三元运算符(意​​味着它可能导致问题)并且使用is_object over isset是否有任何好处/下降?

更新:似乎唯一的区别是静态实例的范围?

2 个答案:

答案 0 :(得分:1)

有趣的问题。就行为而言,据我所知,两个例子之间没有任何区别(范围除外)。

PHP是一种松散类型的编程语言,因此您甚至可以在示例A中省略类属性声明。对于松散类型的语言,似乎总有更多方法可以实现相同的功能!

真正的问题很快就会变成一种设计模式(在这种情况下是数据封装),以确保我们编写的代码遵循由我更聪明的人设计的惯例!

在此示例中,类应该拥有其属性并适当地设置该属性的范围(在本例中为private)并提供逻辑访问器方法。

以下是我的写作方式:

class ExampleA
{
    static private $_instance = null;

    private function __construct(){}

    static public function getInstance()
    {
        if (!self::$_instance instanceof self) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }
}

如果你要将变量包含在方法本身中,严格来说它不是一个类属性。另外,你可能会丢失一点易读性,其他开发人员(不习惯于例B的设计模式)会寻找类属性声明,而不是通过类方法进行挖掘。

答案 1 :(得分:0)

  

在类中保存静态实例并将其保存在返回实例的方法中是否有任何区别?

不,功能没有区别,允许您将静态实例属性的可见性修改为protected或private:

class cExampleA {
    protected static $instance = null;
    // ...
}

顺便说一下,不要使用像$mInstance这样的符号;如今你不需要那些拐杖

另外,看看如何将构造函数设置为受保护的可见性,我假设您希望以后能够扩展该类?在这种情况下,您需要更改getInstance()方法:

public final static function GetInstance() 
{
    if (self::$instance === null) {
        self::$instance = new static;
    }
    return self::$instance;
}

否则,您的构造函数应该只是私有,以便您可以再次使用new self;