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