5

我想衡量人们对使用静态类而不是命名空间的看法。我来自 C++ 背景,非常喜欢它的语法以及它如何让您构建代码。我最近决定需要将我的代码分组为逻辑单元,而不仅仅是文件。例如,我更喜欢像 User::login 这样的调用而不是 user_login。所以,我做了一些谷歌搜索,发现 PHP 有命名空间,我松了一口气。不过我的解脱并没有持续多久,我真的不喜欢这种语法。它给我的函数调用增加了更多的混乱。所以,目前我正在使用静态类来模拟命名空间。这有什么缺点吗?

我在PHP Namespaces vs Classes with static functions中发现了一个类似的问题,但没有太多讨论。

另外,有没有办法避免以下情况:

class Test {
 public static void myFunc() {
  Test::myOtherFunc();
 }
 public static void myOtherFunc() {

 }
}

我认为可以在不指定名称的情况下调用同一类中的函数,但显然不是。是否有任何解决方法(例如在 C++ 中有 using 关键字)。

4

2 回答 2

5

巧合的是,我实际上一直在朝着完全相反的方向前进:

  1. 使用命名空间来组织域类(或函数)
  2. 使用依赖注入,否则我会使用静态类

使用静态类来模拟命名空间的问题是您不能将它们组织到多个文件中,所有内容都必须在一个文件中定义;这很可能取决于个人口味。

静态类的另一件事是,你开始时没有任何状态,慢慢地一些状态管理会慢慢出现,最终你会得到一些奇怪的锁定依赖。状态应该为实例保留。目前我唯一值得注意的静态类是站点范围的配置。

最后,静态类中的自引用是显式的,而在命名空间中它的工作方式与 C++ 完全一样:您指定函数名称,然后首先在命名空间中查找它。

于 2012-08-14T04:03:05.103 回答
4

如果从代码结构的角度来看,静态类方法和命名空间函数没有区别。它们最终都在全球范围内。唯一的区别是,使用静态类方法,您试图伪造 OOP。

因此,如果您真正需要的是独立/实用函数,最好使用命名空间函数。命名空间用于对事物(函数和类)进行分组。

至于你的User::login()例子,这将是一个不好的做法。相反,您应该拥有一个能够包含状态的真实对象。

$mapper = new UserMapper;
$user = new User;
$user->setNickname( $name );

$mapper->fetch( $user );

if ( $user->hasPassword( $password ) )
{
    $user->setLastLogin( time() );
}
else
{
    // log the access attempt
    // set error state
}

$mapper->save( $user );

底线是:如果您使用的是静态结构(函数或方法),则它不是 OOP。你只是在假装它。相反,您应该使用真正的 OOP 和依赖注入

如果你的代码到处都使用静态方法和变量,它会导致类之间的紧密耦合,添加全局状态,并使你的代码库更难维护和测试。这不是特定于 PHP 的。

于 2012-08-14T04:05:49.670 回答