【问题标题】:Static methods or not?静态方法与否?
【发布时间】:2012-03-05 01:07:05
【问题描述】:

我需要使用 PHP 开发一个小型 CMS,现在我正在尝试找出结构。

CMS 将使用一组函数生成。诸如数据库函数、缓存事物、国际化之类的东西。

我想这样做:

  • 使函数成为大型“站点”类的非静态方法的一部分;这样我就可以运行该类的多个实例。不确定我是否需要这样做..

  • 或使用静态方法将函数拆分为单独的类

这里的主要问题是 CMS 应该能够管理多个小型站点,而不仅仅是一个。因此,要么我将所有方法设为静态并添加“站点切换”功能,要么将它们设为我根据要管理的站点实例化的普通对象

以下哪个是最佳选择?

【问题讨论】:

  • 永远不要做一个单一的“一体化”类。由于各种原因,这是不好的做法。查看this question of mine 了解有关类实现的更多信息。
  • 这是一个全新的项目吗?如果是这样,为什么不使用某种 MVC 框架,它们中的大多数都和你之前在你的问题中提到的一样好用。
  • “其中哪一个是最佳选择?” 如果没有对软件工程的全面讨论,很难回答。但是,我想说的是:通常,静态是邪恶的Here's a PHP-based explanation of why 这是another with a terrific metaphor that isn't targeted towards PHP development。我强烈建议避免使用静态来支持依赖注入。如果您想升级自己,请自行完成。如果没有,请尝试使用框架。

标签: php class


【解决方案1】:

静态方法通常是不好的做法。他们引入了很多潜在的问题。

1) 它们引入了隐藏的依赖关系。任意调用 foo::bar() 的代码对 foo 具有依赖性,并且在没有定义 foo 的情况下无法运行。使用 foo::bar() 的对象将正确构造,但如果未定义 foo 将无法使用。

2) 静态是全局变量。全局状态很糟糕,任何东西都可以改变代码,而且它的状态是未知的。您通过使用静态方法牺牲了 OOP 封装所实现的功能和控制。

3) 无法将函数替换为不同的版本

4) 它使单元测试变得不可能。

更多详细信息和代码示例,请参阅this articlethis article

【讨论】:

  • 既然foo::bar()是一个全局状态,它几乎和foo_bar()一样...那它不可能避免全局状态?以内置程序函数为例 - array_push()array_rand() 等。所以如果我在方法的某处使用 array_push(),那么它也会引入全局状态吗?
  • 从技术上讲,这些是静态叶子方法,Misko Hevery 在第二个链接中解决了这些方法:“静态叶子方法是一个滑坡,它正在等待成长并成为问题。静态方法是程序性的! ...就 Math.abs(-5) 而言,...我真的很想写 -5.abs()”。内置函数的问题较少,因为它们不能随时间而变化,并且它们不会受到隐藏依赖的问题(它们将始终可用),尽管它们在测试期间都无法替代 - 您必须测试静态方法和方法你正在尝试测试。
【解决方案2】:

我肯定会建议使用静态类来完成这项工作。走这条路线将为您的所有函数创建一个伪命名空间,因此您不必担心函数名称冲突等,并且它还可以防止您必须传递帮助器类的实例来调用您的一个辅助函数。

【讨论】:

    猜你喜欢
    • 2012-07-14
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 2012-11-12
    • 2011-01-17
    相关资源
    最近更新 更多