3

使用单例模式时。在类中保存静态实例和在返回实例的方法中保存有什么区别吗?

例子:在课堂上。

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 而不是 isset 有什么好处/坏处吗?

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

4

2 回答 2

1

有趣的问题。在行为方面,据我所知,这两个示例之间没有任何区别(范围除外)。

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

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

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

我会这样写:

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 的设计模式)会寻找类属性声明,而不是挖掘类方法。

于 2013-04-03T08:38:42.750 回答
0

在类中保存静态实例和在返回实例的方法中保存有什么区别吗?

不,功能上没有区别,如果您将静态实例属性的可见性修改为受保护或私有:

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;再次使用。

于 2013-04-03T08:58:44.370 回答