关于php:何时使用静态方法或简单类方法?

when to use static method or simple class method?

我很困惑是使用静态方法还是简单方法。

让我举个例子,我正在使用Zend框架1项目。我的课很像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Example1
{
    public static function getVariable() {
       return is_numeric(Zend_Registry::get('config')->Variable) ? Zend_Registry::get('config')->Variable : 0;
    }

    public function calculateSome($param1, $param2) {
        $response = array();
        if($param2 == 0) {
              $response = number_format(($param1 * self::getvariable()) /100);
        } else {
              $response = $param1;
        }
        return $response;
    }
}

用途:

  • 目前我在整个项目中得到的是像Example1::getVariable()这样的可变值。
  • 计算,比如首先实例化一个类$class1 = new Example1();,然后调用类似$class1->calculateSome(1, 0);的函数。
  • 我很困惑,把calculateSome()改成public static,像这样叫Example1::calculateSome(1, 0),还是原封不动。

    我找到了使用static的链接=>何时使用静态vs实例化类

    但我不明白它说的是什么。


    您可以在这里找到一个很长的答案:如何不使用静态方法破坏您的可测试性

    它的tl;dr版本是:

    • 静态方法只不过是一个名称空间函数,Foo::bar()foo_bar()没有明显区别。
    • 无论何时调用静态方法或函数,都会对依赖项进行硬编码。读取$bar = Foo::bar();的代码具有对特定Foo类的硬编码依赖性。如果不更改源代码的那一部分,就不可能更改Foo所指的内容。
    • 对象是"软"依赖项。$bar = $foo->bar();是灵活的,它允许改变$foo所指的内容。您可以将此与依赖注入一起使用,以将代码与其他代码分离:

      1
      2
      3
      4
      function baz(Foo $foo) {
          $bar = $foo->bar();
          ...
      }
    • 你可以随时从任何地方打电话给Foo::bar()。如果Foo::bar有它所依赖的一些依赖项,那么很难保证在调用方法时这个依赖项是可用的。需要对象实例化需要运行对象的构造函数,这样可以强制设置对象的其余方法所依赖的要求。

    • 构造函数以及将对象注入到其他函数中的依赖项对于

    • 在代码库中创建接缝,使其能够"分离"并以灵活的方式组合在一起。
    • 将检查放在战略位置,以确保满足代码的某些部分的要求(在对象实例化时,构造函数强制其世界的一小部分,即其对象的健全状态),这使得本地化和包含失败变得更加容易。
    • 想象一下,将你的应用划分成若干个区域,在每个区域之间放置防火墙,由主管管理每个区域,而不是每个人都在同一个房间里跑来跑去。

    • 在编写new Class时,您也可以编写Class::staticMethod(),硬编码的依赖关系是相同的。

    所以决定归结为:

    • 这门课有什么要求?它是否需要确保在运行任何代码之前满足某些前提条件(例如,数据库连接需要可用),或者所有方法都只是独立的小助手方法?
    • 你有多可能想用这门课代替另一门课?此类是否会产生副作用(例如,写入文件、修改某些全局状态),这些副作用可能并不总是可取的,因此在某些情况下,它的不同版本可能会有用?
    • 您可能同时需要该类的多个实例,或者该类的性质是否使得不需要单独的实例?

    开始使用单元测试,这要求您将应用程序拆开,分别测试每个小部分以确保其正常工作,然后您将看到对象实例化和依赖注入的优势所在。


    当方法涉及到基于实例的属性/更改时,您应该保留它non-static

    如果它是整个type所需的方法,则使用static。

    例如,您可以通过以下代码段跟踪创建的实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class Product {
     static $count;
     private $name;

     public function __construct($name) {
        $this->name = $name;
        self::$count++;
     }
     public function getName() {
        return $this->name;
     }
     public static function getCount() {
         return self:$count;
     }
    }

    $productA = new Product('A');
    $productB = new Product('B');

    echo $productA->getName(). ' and ' . $productB->getName(). '<br />'. PHP_EOL;
    echo 'Total made products :' . Product::getCount();