我有一个包含10个方法的类我总是需要使用其中一种方法。现在我想知道,哪种方法更好?
class cls{
public function func1(){}
public function func2(){}
.
.
public function func10(){}
}
$obj = new cls;
$data = $obj->func3(); // it is random, it can be anything (func1, or func9 or ...)
或
class cls{
public static function func1(){}
public static function func2(){}
.
.
public static function func10(){}
}
cls::func3(); // it is random, it can be anything (func1, or func9 or ...)
这是一个有趣的主题。我会给你一个以设计为导向的答案。
在我看来,在一个好的OOP体系结构中,永远不应该使用静态类/函数。
当您使用static时,这是在没有类实例的情况下调用函数。主要原因通常是表示一个不应该多次实例化的服务类。
我会给你3个解决方案(从最坏到最好)来实现这一点:
静态
静态类(只有静态函数)阻止您使用许多OOP特性,如继承、接口实现。如果你真的认为什么是静态函数,那么它是一个按类名称命名的函数。PHP中已经有了名称空间,为什么还要添加另一层呢?
另一个很大的缺点是,您无法定义静态类和使用它的类的明确依赖关系,这对应用程序的可维护性和可扩展性来说是一件坏事。
辛格尔顿
singleton是一种强制类只有一个实例的方法:
<?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;
}
}
这是一种更好的方法,因为您可以使用继承,接口和方法将在实例化的对象上调用。这意味着你可以定义契约,并与使用它的类使用低耦合。然而,有些人认为singleton是一种反模式,尤其是因为如果你想拥有两个或多个具有不同输入属性的类实例(比如连接到两个不同数据库的经典示例),你就必须使用singleton对所有代码进行大规模重构。
服务
服务是一个标准类的实例。这是一种合理化代码的方法。这种体系结构被称为SOA(面向服务的体系结构)。我举一个例子:
如果您想添加一个方法来向消费者销售商店中的产品,并且您有类Product
、Store
和Consumer
。您应该在哪里实例化此方法?我可以保证,如果你认为今天这三节课中的一节课更合乎逻辑,那么明天可能会是其他课。这会导致大量重复,并且很难找到您要查找的代码。相反,您可以使用像SaleHandler
这样的服务类,它将知道如何操作您的数据类。
最好使用一个框架来帮助您将它们相互注入(依赖注入),以便充分利用它们的潜力。在PHP社区中,您有一个在Symfony中实现这一点的好例子。
综上所述:
如果你没有一个框架,单例当然是一个选择,即使我个人更喜欢一个简单的文件,在那里我进行手动依赖注入。
如果你有一个框架,可以使用它的依赖项注入功能来做这种事情。
您不应该使用静态方法(在OOP中)。如果您在某个类中需要一个静态方法,这意味着您可以创建一个包含此方法的新单例/服务,并将其注入到需要它的类的实例中。
答案取决于这些方法的作用。如果您使用它们来改变当前对象的状态,则需要使用实例方法调用。如果它们是独立的功能,那么您可以使用静态版本,但我会质疑它们为什么是类的一部分。
因此,static
方法之间存在非常基本的差异。
要使用静态函数,不需要将类初始化为对象。例如,Math.pow()
,这里的.pow()
(在Java中;但解释仍然成立)是一个静态方法。
一般规则是使helper方法成为static
。
因此,例如,如果你有一个Math类,你不想用只帮助其他更重要的类的类来填充垃圾收集器。
如果你愿意的话,你可以把它用作动态初始化程序!
假设你有一个类RSAEncryptionHelper
,现在你通常可以在没有任何参数的情况下初始化它,这将生成一个密钥大小为(比如)512
位的对象;但是您还有一个重载的对象构造函数,它从其他类中获取所有属性:
$a = new RSAEncryptionHelper::fromPrimeSet(...);
在PHP类中,您可以使用class/methods/attributes:Abstract、Static
、Private、Public等。。。最好的方法是知道如何根据需要将它们混合在一个类中,我将给你一个基本的例子:
在Person
类中,您有private和public方法,但您有一个名为"get_nationality"的方法,所以这是您在其他地方需要的函数,但您还没有安装Person
类,因此,您将该方法设置为STATIC,这样您就可以在不安装任何Person
类的情况下调用"get_nationality"方法,这将使您的业务模型更加优化,进而使CPU中的资源更加丰富。
静态函数也非常有用,但当我必须创建与类独立相关的函数时,我通常会生成特征。
我不知道这种方法是否更好,但大多数时候我觉得它很有用。
只是在这里分享我的方法,这样我就可以更多地了解它的优点和缺点。
您可以认为是一家工厂。你会给出一些材料,它会给你同样的输出。然后您应该使用静态函数。
class ProductDetails
{
public static function getRow($id, PDO $pdo): SingleProduct
{
// this function will return an Object.
}
}
我不是在这里定义Object。只要您需要一个单一产品,您就可以简单地执行ProductDetails::getRow(10, $pdo);