【问题标题】:Best practice on PHP singleton classes [duplicate]PHP单例类的最佳实践[重复]
【发布时间】:2012-02-05 07:13:47
【问题描述】:

可能重复:
Who needs singletons?

我总是根据最佳实践写作,但我也想了解为什么给定事物是最佳实践

我在一篇文章中读到过(遗憾的是我不记得了)单例类更喜欢被实例化,而不是使用静态函数创建并使用范围解析运算符 (::) 访问。因此,如果我有一个包含我所有要验证的工具的类,简而言之:

class validate {
    private function __construct(){}
    public static function email($input){
        return true;
    }
}

有人告诉我这被认为是不好的做法(或至少被警告过),因为诸如垃圾收集器和维护之类的事情。因此,对“作为静态方法的单例类”的批评想要的是,我实例化了一个我 100% 确定我只会实例化一次的类。对我来说,这似乎是在做“双重工作”,因为一切都准备好了。我错过了什么?

对此事有何看法?当然,这不是生死攸关的问题,但如果有选择,不妨以正确的方式做一件事:)

【问题讨论】:

标签: php oop class design-patterns singleton


【解决方案1】:

嗯,这实际上不是单例;单例确保您只有一个类的单个实例,并且这里没有方法可以检索 Validate 的单个实例。您在这里的设计似乎是一个静态类。这不会导致垃圾收集器出现问题(至少是您放在这里的代码),因为无论如何这都会被加载到内存中。

【讨论】:

  • 这当然可以解释为什么我找不到逻辑,因为这种类会是一个问题。所以单例并不是一个只实例化一次的类,而是该方法 - 也 - 只被调用一次?
【解决方案2】:

【讨论】:

  • 感谢您的链接;已经在阅读它们了。我想我可能误解了什么是单例(在下面的回复中指出)
  • @MarkHünermundJensen 认为如此阅读您的问题。 Tas 为什么发布链接 ;)。
  • 请注意依赖注入不等于依赖注入容器。 DI绝对是个好东西; DIC 是实现这一点的一种方式,不一定是一种万能的解决方案(尽管它目前在 PHP 世界中非常“流行”)。服务定位器或类似模式也可能是打破依赖关系的可接受方式。
  • 鉴于这篇文章只是收集了来自 SO 和外部网站的链接,我认为它应该是一个社区 Wiki。
  • @gordon 社区 Wiki 完成 :)。
【解决方案3】:

单例对象是只实例化一次的对象。那和Singleton Pattern不一样,这是一个(反)模式如何写一个可以只实例化一次的类,Singleton(大S 开头):

“确保一个类只有一个实例,并提供一个全局访问点。”

就 PHP 而言,您通常不需要实现单例模式。事实上,当您要求最佳实践时,您应该避免这样做,因为这是不好的实践

此外,您发现的大多数 PHP 代码示例都是该模式的半就绪实现,忽略了 PHP 的工作原理。这些虚假的实现不符合模式中的“确保”。

这也说明了一些事情:通常不需要它。如果一个草率的实现已经完成了工作,甚至没有接近模式的用途,那么错误的模式已经被用于这种情况,它开始成为一种反模式

在 PHP 中,通常不需要不惜一切代价确保一个类只有一个实例,PHP 应用程序并不像您需要的那样复杂(例如,没有可能需要引用原子实例的多个线程)。

通常留下的是类实例的全局访问点,这是大多数 PHP 开发人员(错误)使用的模式。正如今天所知,使用这种“单例”会导致全局静态状态的标准问题,这些问题会在多个级别上将复杂性引入您的代码并降低可重用性。作为程序员,您失去了以灵活方式使用代码的能力。但灵活性是解决问题的一项非常重要的技术。程序员整天都在解决问题。

因此,在应用设计模式之前,需要评估利弊。仅仅经常使用一些模式是没有帮助的。

对于初学者,我想说的是,只需编写您的类并注意它们在应用程序逻辑的其他部分中的实例化方式和时间,以便保持灵活性。

【讨论】:

  • 你的第一句话是矛盾的:)。 -1 。 “PHP 应用程序没有那么复杂”也是 -1。您可以使用任何语言编写复杂的软件。设计模式与软件架构有关,与底层技术无关。我会投三票,但我不能。 :)
  • @Geo C. 我这么写的一个原因是 PHP 应用程序通常不需要跨进程和线程的原子性,这是 more中线程安全单例的一种用例> 复杂的软件。您可能判断得太快了,因为您认为确实攻击了某些特定语言,但事实并非如此。只是普通的PHP代码不需要模式的实现。如果您仍然需要它,我什至会在我的博客上提供该模式。
猜你喜欢
  • 2012-05-12
  • 2013-01-08
  • 1970-01-01
  • 2014-03-24
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-28
相关资源
最近更新 更多