【问题标题】:Using a class as namespace使用类作为命名空间
【发布时间】:2010-06-19 12:07:15
【问题描述】:
有什么理由我不应该使用静态方法创建最终类以避免调用某些内部函数?
final class ModuleGlobalFunctions {
static public function generateWord {
$result = '';
while (strlen($result) < 12) {
$result = self::generateSyllable();
}
return $result
}
static private function generateSyllable() {
// Generates a random syllable.
// …
}
}
$word = ModuleGlobalFunctions::generateWord();
// It raises an error.
$syllable = ModuleGlobalFunctions::generateSyllable();
【问题讨论】:
标签:
php
class
drupal
static
final
【解决方案1】:
创建一个类来屏蔽私有函数是个好主意。这样,类中的公共方法可以调用私有方法,而无需从类外部调用私有方法。
创建一个类final也是一个好主意,因为这表明该类在设计时没有考虑到重载,并使类更简单。
将类设为static 是个坏主意,因为它将调用者与类紧密耦合。如果您调用 Test::generateWord(),这将始终使用 Test 类。但是,如果你使用 $test->generateWord(),你可以传入另一个类,它会创建其他单词。这样可以更轻松地更改软件并更轻松地对其进行单元测试。
【解决方案2】:
嗯,就个人而言,我建议使用类来对类似的逻辑进行分组。所以在你的情况下(你提供的例子),这是个好主意。
至于决赛,这是一个折腾。我更喜欢使用 abstract 来防止实例化(因为 PHP 不支持 static 类)。如果你确实使用 final,我建议添加一个私有构造函数来防止实例化:private function __construct() {}...
就个人而言,我喜欢保持静态的概念。原因是三个方面。首先,它在内存上更容易(因为没有要跟踪的实例)。其次,它更快(静态方法调用比实例方法调用更快)。第三,更重要的是,它是有道理的。实例有一个状态(这就是它们是实例的原因)。你的班级需要一个状态吗?如果是这样,那么使用一个实例。如果不是,那正是 static 类的用途......
至于 Sjoerd 提到的传递实例,您可以使用静态类来做到这一点(实际上与实例相比,耦合更紧密)。这就是原因。除非您需要(并检查)接口或继承,否则您不知道对象是否实际实现了方法generateWord()。但是,如果您传入一个回调,那么如何访问该方法(或其底层构造)并不重要,重要的是它具有相同(或相似)的语法(关于参数和返回值)。现在,接口是一个更好的解决方案(因为它强制执行接口),但它们需要对 OOP 有相当深入的理解才能正确设计。在紧要关头,回调将非常适合这种情况...