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; } } |
用途:
我很困惑,把
我找到了使用static的链接=>何时使用静态vs实例化类
但我不明白它说的是什么。
您可以在这里找到一个很长的答案:如何不使用静态方法破坏您的可测试性
它的tl;dr版本是:
- 静态方法只不过是一个名称空间函数,
Foo::bar() 与foo_bar() 没有明显区别。 - 无论何时调用静态方法或函数,都会对依赖项进行硬编码。读取
$bar = Foo::bar(); 的代码具有对特定Foo 类的硬编码依赖性。如果不更改源代码的那一部分,就不可能更改Foo 所指的内容。 对象是"软"依赖项。
$bar = $foo->bar(); 是灵活的,它允许改变$foo 所指的内容。您可以将此与依赖注入一起使用,以将代码与其他代码分离:1
2
3
4function baz(Foo $foo) {
$bar = $foo->bar();
...
}你可以随时从任何地方打电话给
Foo::bar() 。如果Foo::bar 有它所依赖的一些依赖项,那么很难保证在调用方法时这个依赖项是可用的。需要对象实例化需要运行对象的构造函数,这样可以强制设置对象的其余方法所依赖的要求。构造函数以及将对象注入到其他函数中的依赖项对于
- 在代码库中创建接缝,使其能够"分离"并以灵活的方式组合在一起。
- 将检查放在战略位置,以确保满足代码的某些部分的要求(在对象实例化时,构造函数强制其世界的一小部分,即其对象的健全状态),这使得本地化和包含失败变得更加容易。
- 在编写
new Class 时,您也可以编写Class::staticMethod() ,硬编码的依赖关系是相同的。
想象一下,将你的应用划分成若干个区域,在每个区域之间放置防火墙,由主管管理每个区域,而不是每个人都在同一个房间里跑来跑去。
所以决定归结为:
- 这门课有什么要求?它是否需要确保在运行任何代码之前满足某些前提条件(例如,数据库连接需要可用),或者所有方法都只是独立的小助手方法?
- 你有多可能想用这门课代替另一门课?此类是否会产生副作用(例如,写入文件、修改某些全局状态),这些副作用可能并不总是可取的,因此在某些情况下,它的不同版本可能会有用?
- 您可能同时需要该类的多个实例,或者该类的性质是否使得不需要单独的实例?
开始使用单元测试,这要求您将应用程序拆开,分别测试每个小部分以确保其正常工作,然后您将看到对象实例化和依赖注入的优势所在。
当方法涉及到基于实例的属性/更改时,您应该保留它
如果它是整个
例如,您可以通过以下代码段跟踪创建的实例:
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(); |