Статические методы: они все еще плохо относятся к PHP 5.3 поздней статической привязке?

Если вы ищете причины, почему статические методы являются плохими, первое, что вы обнаружите, это потому, что вы не можете переопределить его, когда вы тестируете устройство.

Так это все еще верно, учитывая, что в PHP 5.3 вы можете делать все, что хотите, с введением static:: ?

Добавить:

http://sebastian-bergmann.de/archives/883-Stubbing-and-Mocking-Static-Methods.html

Обратите внимание, что он объясняет, как использовать синглтон без какой-либо проблемы с тестированием:

  • http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html

Related of "Статические методы: они все еще плохо относятся к PHP 5.3 поздней статической привязке?"

Если у вас есть статическая функция-член, она обычно может быть свободной. Обычная реакция заключается в том, что кодер выбрал статическую функцию-член только из-за мифа о том, что «все должно быть в объекте».

Вот почему люди отговаривают их.

И, поскольку это не очень убедительный аргумент, эти люди вместо этого указали на модульное тестирование. Не уверен, что они сделают сейчас.

Статические методы сами по себе не плохи. Иногда некоторые операции не имеют смысла требовать от конкретного объекта. Например, функция, подобная квадратному корню, будет иметь больше смысла быть статичной.

 Math::sqrRoot(5); 

вместо необходимости создавать экземпляр объекта Math, а затем вызывать функцию.

 $math = new Math(); $result = $math->sqrRoot(5); 

Еще труднее проверить причину, но не единственную. Статические методы обеспечивают глобальный доступ, а глобальный доступ – плохой.

Конечно, вы обнаружите, что есть еще один глобальный доступ к объектам, и это создает его с помощью «нового». Объекты должны быть созданы где-то, поэтому мы не можем устранить это (хотя сведение к минимуму это хорошая идея). Статические методы как глобальный доступ к классу являются плохими, если только он не заменит «новый» на более высокий уровень программирования:

 $user = new User(); $user->setPointsTo(100); // vs $user = User::with100StartingPoints(); 

В этом случае я создал код, который более читабельен, не злоупотребляя глобальным доступом («новый» должен быть вызван в любом случае).

Редактирование: позвольте мне привести пример, как статические методы могут быть смертью тестируемости (обратите внимание, как в приведенном выше примере вам даже не нужно издеваться над статическим методом, но может легко протестировать новый и статический метод, тот же результат). Давайте используем ваш пример регистратора:

 class Logger { public static function log($text) { // etc } } class AccessControl { public function isAllowed(User $user, $action) { // do stuff, determine if $allowed if (!$allowed) { Logger::log('user X was not allowed to do Y'); } // do stuff } } 

Мы не можем проверить этот метод чисто из-за глобального вызова Logger :: log. Это будет зависеть от правильной работы класса Logger.