【问题标题】:Should Helper Functions be in a Class?辅助函数应该在一个类中吗?
【发布时间】:2014-02-07 21:32:05
【问题描述】:

在考虑到 OOP 重写我过去的项目时,我将代码分解为设备、设施等类。

在转向更面向对象的方法之前,我只是将我的所有帮助函数都放在了一个包含的“functions.php”文件中。以Devices为例,最好有一个Devices类用于我的对象特定属性/方法,然后有一个DeviceManager类来存储getDeviceByName、getDeviceByID等函数?

据我了解,OOP 更多的是关于可读性/可管理性而不是其他任何东西,为什么我认为目的只是用 DeviceManager::GetDevice("Computer1") 之类的东西代替 GetDeviceByName("Computer1")

【问题讨论】:

  • 如果您在类中使用静态方法,那么它们与简单的命名空间函数没有什么不同。再说一次,那不是 OOP
  • 是的,您实际上只需要为这些函数定义一些命名空间。但无论哪种方式,您都需要将类似的函数分组到同一个命名空间或同一个类中,而不是将所有内容放在一个文件中:)

标签: php function oop


【解决方案1】:

如果您正在考虑将类用作命名空间,那么您也可以使用实际的命名空间:

namespace MyCollectionOfFunctions;
function printMyName($name) {
    echo $name;
}

然后你可以像这样使用函数:

use MyCollectionOfFunctions as fn;
echo fn\printMyName('Brett Powell');

函数没有错。不要让任何人告诉你它们属于一个类,就像静态方法一样。 可以那样做,但既然我们有命名空间,那就没有理由这样做了。

【讨论】:

    【解决方案2】:

    在 C# 或 Java 等 OOP 语言中,您根本无法在类之外拥有函数,因此没有问题。这并不意味着你在做 OOP,这是一种心态。

    在 PHP 中,您可以将相关函数放入命名空间或类中(在命名空间内)。这取决于你,没有正确或错误的方法。就我个人而言,我会将它们放到一个类中,因为这就是我在 C# 中的做法,而且它对生产力有所帮助:我将相关功能分组在一个地方(类)。更容易管理。

    但严格从编程的角度来看,没有区别,您的代码不会更干净/解耦或更多 OOP,因为您已将函数放入类或命名空间中

    【讨论】:

      【解决方案3】:

      将命名空间或类用于静态函数时的一些优点。

      1. 命名空间和类名有助于区分函数。您可以避免命名冲突。

      2. 当您想利用 IDE 的自动建议时,DPDate::FirstDayOfMonth() 优于 FirstDayOfMonth()。

      3. 真正的关键在于凝聚力和解耦。

      【讨论】:

      • 为什么类在命名空间之上?
      • 你也可以使用命名空间。我同意。
      • 好吧,如果静态方法与该类相关,它们应该只在一个类中。 DateTime::createFromFormat 方法就是一个很好的例子。
      【解决方案4】:

      您必须遵守以下规则:

      1. 在 OOP 中,您必须始终使用 CLASS
      2. 您的方法必须具有单一职责
      3. 避免泛型帮助类,类必须具有简单而具体的职责
      4. 不要使用静态方法,使用策略(传递对象 throw 参数)来调用方法,这样您就可以创建一个 Mock 来测试您的方法。
      5. 避免使用私有方法,这会使您的类难以测试

      记住这一点,你就会编写出干净的代码。 =)


      就第 4 项回答 Eric:这段代码将使用静态方法:

      public function myFunction() {
          $deviceId = DeviceManger::getDeviceId('computer 1');
          // Rest of code using the device id 
      }
      

      这样我不能模拟设备ID的返回,这样我可以:

      public function myFunction(deviceManger) {
          $deviceId = deviceManager->getDeviceId('computer 1');
          // Rest of code using the device id 
      }
      

      测试函数中带有mock的代码:

      $deviceManager = $this->getMock('DeviceManager');
      $deviceManager->method('getDeviceId')->returnValue(1);
      myFuncion($deviceManager);
      

      【讨论】:

      • 你能详细说明一下4吗? 5 听起来也不是特别好的建议
      • 是辅助函数。我真的不认为他需要嘲笑什么。它只是输入/输出功能。没有内部成员需要被嘲笑。事件传递的参数可以被mock,不是吗。
      • Ethan 辅助函数在它的测试中可能不需要模拟,但是需要辅助函数的方法将需要,就像我现在发布的代码一样。
      • MikeSW,为什么会有不好的规则?
      • 1.不! 2. 好的 3. 有争议的 4. 见 3 5. 不!私有方法是内部细节,它们首先不应该是可测试的。在 OOP 和一般开发中没有规则。有些原则应该被理解和尊重,但也应该适应问题,有时甚至被忽略。
      猜你喜欢
      • 1970-01-01
      • 2013-04-27
      • 2021-10-09
      • 2021-05-07
      • 2022-01-08
      • 1970-01-01
      • 2022-08-13
      • 2019-08-05
      • 2019-08-02
      相关资源
      最近更新 更多