【问题标题】:when to use static method or simple class method?什么时候使用静态方法或简单的类方法?
【发布时间】:2014-10-15 00:10:11
【问题描述】:

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

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

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;
    }
}

用法:

  1. 目前,我在整个项目中获得了像 Example1::getVariable() 这样的变量值。
  2. 和计算就像首先实例化一个类$class1 = new Example1();,然后像$class1->calculateSome(1, 0);一样调用函数

我很困惑将calculateSome() 更改为public static 并像这样调用Example1::calculateSome(1, 0) 还是保持原样。

我找到了何时使用静态链接 => When to use static vs instantiated classes

但我不明白它在说什么。

【问题讨论】:

标签: php zend-framework static instantiation


【解决方案1】:

您可以在这里找到长答案:How Not To Kill Your Testability Using Statics

它的 TL;DR 版本是:

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

    function baz(Foo $foo) {
        $bar = $foo->bar();
        ...
    }
    
  • 您可以随时随地拨打Foo::bar()。如果Foo::bar 有一些依赖 依赖,则很难保证在您调用该方法时该依赖可用。要求对象实例化需要运行对象的构造函数,这可以强制设置对象的其余方法可以依赖的要求。

  • 构造函数以及将对象注入到其他函数中的功能非常强大

    1. 在您的代码库中创建接缝,以便“拆开”并以灵活的方式将其组合在一起
    2. 将检查置于战略位置,以确保满足代码的某些部分的要求(在对象实例化时,构造函数强制其世界的一小部分,即其对象的健全状态),这使得本地化变得更加容易并包含故障。

    把它想象成划分你的应用程序,并在每个隔间之间放置防火墙,并由主管负责每个隔间;而不是每个人都在同一个房间里跑来跑去。

  • 任何时候写new Class,也可以写Class::staticMethod(),硬编码的依赖是一样的。

所以决定归结为:

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

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

【讨论】:

    【解决方案2】:

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

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

    例如,你可以通过这个 sn-p 跟踪创建的实例:

    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();
    

    【讨论】:

    • 从我上面的代码中,我是否应该将我的函数更改为public static function calculateSome(1,0),因为这个函数会根据传递的参数进行一些计算。
    • 如果该类被称为“计算器”并且您不需要存储任何基于实例的成员,那么您可以将其保留为“静态”imo
    猜你喜欢
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 2011-01-06
    • 2010-09-17
    • 1970-01-01
    • 2019-10-06
    相关资源
    最近更新 更多