我有一个包含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 ...)
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 ...)
答案 0 :(得分:52)
这是一个有趣的主题。我会给你一个以设计为导向的答案。
在我看来,你绝不应该在一个好的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;
}
}
这是一种更好的方法,因为您可以使用继承,接口和您的方法将在instanciated对象上调用。这意味着您可以定义合同并使用low coupling与使用它的类。但是有些人会考虑singleton as an anti pattern,特别是因为如果你想让你的类的2个或更多个实例具有不同的输入属性(比如连接到2个不同数据库的典型例子),你不能没有对你所有的重构使用单例的代码。
<强>服务强>
服务是标准类的实例。这是一种合理化代码的方法。这种架构称为SOA(面向服务的架构)。我举个例子:
如果您想添加一种方法来将商店中的商品销售给消费者,并且您有类Product
,Store
和Consumer
。你应该在哪里实例化这个方法?我可以保证,如果你认为今天这三个课程中的一个更合乎逻辑,明天就可能是其他任何东西。这会导致大量重复,并且很难找到您要查找的代码的位置。相反,您可以使用像SaleHandler
这样的服务类,它将知道如何操作您的数据类。
使用框架帮助您将它们注入彼此(dependency injection)是一个好主意,以便充分发挥它们的作用。在PHP社区中,您可以在Symfony2中有一个很好的实现示例。
总结一下:
如果你没有框架,单身人士肯定是一个选择,即使我个人更喜欢我手工依赖注入的简单文件。
如果您有框架,请使用其依赖注入功能来执行此类操作。
您不应该使用静态方法(在OOP中)。如果你的某个类需要一个静态方法,这意味着你可以创建一个包含这个方法的新单例/服务,并将它注入需要它的类的实例。
答案 1 :(得分:3)
因此,static
方法存在非常基本的差异。
要使用静态函数,您不需要将类初始化为对象。例如,Math.pow()
,这里.pow()
(在Java中;但解释仍然存在)是静态方法。
一般规则是制作辅助方法static
。
因此,例如,如果你有一个Math类,你就不希望用只帮助其他更重要的类的类来填充垃圾收集器。
如果您愿意,可以将它用作动态初始值设定项!
假设您有一个类RSAEncryptionHelper
,现在您通常可以在没有任何参数的情况下初始化它,这将生成一个密钥大小为(比如)512
位的对象;但你也有一个重载的对象构造函数,它从其他类中获取所有属性:
$a = new RSAEncryptionHelper::fromPrimeSet(...);
答案 2 :(得分:3)
答案取决于这些方法的作用。如果您使用它们来改变手头对象的状态,则需要使用实例方法调用。如果它们是独立的功能,那么你可以使用静态版本,但后来我会质疑它们为何成为一个类的一部分。
答案 3 :(得分:0)
在PHP类中,您可以使用 class / methods / attributes :Abstract,Static
,Private,Public等...
最好的方法是根据需要知道如何在一个类中混合它们,我将给你一个基本的例子:
在Person
类中,您有私有和公共方法,但您有一个名为&#34; get_nationality &#34;所以这是你需要的其他地方的功能,但你还没有安装Person
类,所以这个方法你把它作为 STATIC 这样你可以调用&#34 ;的 get_nationality 强>&#34;没有安装任何Person
类的方法,这使您的业务模型更加优化,反过来又成为CPU中的资源。
答案 4 :(得分:0)
静态功能也非常有用,但 当我必须创建与类独立相关的函数时,通常会制作 traits 。
我不知道这种方法是否更好,但是大多数时候我发现它很有用。
只需在这里分享我的方法,以便我可以进一步了解其优缺点。