这是一个有趣的话题。我要给你一个以设计为导向的答案。
在我看来,你永远不应该在一个好的OOP架构中使用静态类/函数。
使用 static 时,这是在没有类实例的情况下调用函数。主要原因通常是表示不应多次实例化的服务类。
我将为您提供3解决方案(从最差到最好)来实现这一目标:
静态的
静态类(仅包含静态函数)会阻止您使用许多 OOP 功能,如继承、接口实现。如果您真的想到什么是静态函数,那么它是一个由其类名称命名的函数。你已经在PHP中拥有命名空间,那么为什么要添加另一个层呢?
另一个很大的缺点是,您无法定义静态类和使用它的类的明确依赖关系,这对于应用程序的可维护性和可伸缩性来说是一件坏事。
单身 人士
单例是强制类只有一个实例的一种方法:
<?php
class Singleton {
// Unique instance.
private static $instance = null;
// Private constructor prevent you from instancing the class with "new".
private function __construct() {
}
// Method to get the unique instance.
public static function getInstance() {
// Create the instance if it does not exist.
if (!isset(self::$instance)) {
self::$instance = new Singleton();
}
// Return the unique instance.
return self::$instance;
}
}
这是一种更好的方法,因为您可以使用继承,接口和您的方法将在实例化对象上调用。这意味着您可以定义协定,并与使用它的类使用低耦合。然而,有些人认为单例是一种反模式,特别是因为如果你想拥有2个或更多具有不同输入属性的类实例(如连接到2个不同数据库的经典示例),你不能不使用单例对所有代码进行大规模重构。
服务
服务是标准类的实例。这是一种使代码合理化的方法。这种架构称为SOA(面向服务的架构)。我举个例子:
如果要添加一个方法,将商店中的产品销售给消费者,并且您有类 和 。应在哪里实例化此方法?我可以保证,如果你认为今天这三门课中的一门课更合乎逻辑,那么明天可能会是其他任何东西。这会导致大量重复,并且很难找到您要查找的代码的位置。相反,您可以使用例如一个服务类,它将知道如何操作您的数据类。Product
Store
Consumer
SaleHandler
使用一个框架来帮助你将它们相互注入(依赖注入)是一个好主意,以便充分发挥它们的潜力。例如,在PHP社区中,你有一个很好的例子,在Symfony中实现它。
总结一下:
-
如果你没有一个框架,单例肯定是一个选择,即使我个人更喜欢一个简单的文件,在那里我进行手动依赖注入。
-
如果你有一个框架,使用它的依赖注入功能来做那种事情。
-
不应使用静态方法(在 OOP 中)。如果在其中一个类中需要静态方法,这意味着可以创建一个包含此方法的新单例/服务,并将其注入到需要它的类的实例中。