Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php:单例VS完全静态类?什么时候用什么?_Php_Oop_Class_Static_Singleton - Fatal编程技术网

Php:单例VS完全静态类?什么时候用什么?

Php:单例VS完全静态类?什么时候用什么?,php,oop,class,static,singleton,Php,Oop,Class,Static,Singleton,我知道singleton强制创建一个类。但是,如果我不直接访问实例,为什么实例会存在呢?为什么使用这种模式,在静态方法和数据中使用完整的静态类不是更容易吗?静态类和单例的主要区别在于,在使用静态类时,您需要在代码中的任何地方硬编码类名: StaticClass::doSomething(); StaticClass::doSomethingElse(); 使用单例时,只需硬编码类名一次: $singleton = SingletonClass::getInstance(); // other

我知道singleton强制创建一个类。但是,如果我不直接访问实例,为什么实例会存在呢?为什么使用这种模式,在静态方法和数据中使用完整的静态类不是更容易吗?

静态类和单例的主要区别在于,在使用静态类时,您需要在代码中的任何地方硬编码类名:

StaticClass::doSomething();
StaticClass::doSomethingElse();
使用单例时,只需硬编码类名一次:

$singleton = SingletonClass::getInstance();

// other code does not need to know where $singleton came from,
// or even that class SingletonClass exists at all:
$singleton->doSomething();
$singleton->doSomethingElse();
另一个重要的区别是,单例类可以是层次结构的一部分,并且可以实现接口


这并不意味着Singleton(模式)是好的,应该被广泛使用。但是它比直接使用静态类要好。

不久前,有人问我使用singleton比使用静态类有什么好处,下面是我的回答:

  • 静态类会导致不可见的依赖关系,即使用静态类的类,但该类不是类接口的一部分。 Singleton也允许这样做,因为它提供了全局访问点,但它的实例可以作为参数传递给类/方法
  • 如果有任何初始化,比如connect方法,那么应该从每个类方法调用它,这会导致重复的代码。另一方面,singleton的初始化是在构造函数中执行的,从getInstance()只调用一次 方法
  • Singleton可以很容易地在工厂中重构,向getInstance()方法添加一个参数并返回不同的实例
  • 静态类更难扩展,因为如果我们想要覆盖一个方法,即在类中使用self::methodName()调用的方法,我们也应该覆盖调用方(尽管在PHP5.3中有一个后期静态绑定,可以用来避免这些问题)
  • 如果您需要添加所有方法都需要的参数,您可以在singleton中轻松地执行此操作,因为只有一个访问点,但在静态类中则不行
    • [Edit]:我在下面写的东西实际上是完全错误的。几年前的一次反对票提醒了我这个答案。它们确实有目的;)

      一个单例只存在一次,但它可以有内部状态,而不是静态类。例如,您可以将其用作全局注册表,这是静态类无法做到的

      [编辑:]然而,接下来发生的事情与以往一样真实


      然而,单身是否是一个好主意仍有争议。它们将全局状态引入到应用程序中,这会使测试变得非常困难。但这是另一个讨论。

      (相关)这里有一些与语言无关的好答案:(建议)您当然可以使用静态类作为全局注册表。是什么阻止静态类也具有内部状态(
      私有静态成员)?仅供参考,您给出的第一个原因在PHP5.3中不再正确,您可以这样做:
      $class='StaticClass'
      ,然后:
      $class::doSomething()$类::doSomethingElse()final
      类——也许tin上没有说“static”,但我们都同意这是一个静态的类。@Jon使用
      final
      关键字来防止子类重写要扩展的方法或类。如果您选择将一个方法或类声明为
      final
      ,这是您的体系结构决定。它与调用只包含静态方法的类的行话无关,
      static
      @Darhazar:+1最后有人用非常简单的几点解释了为什么singleton可以比静态类更好。