Статические методы: они все еще плохи, учитывая позднюю статическую привязку PHP 5.3? - PullRequest
11 голосов
/ 17 мая 2011

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

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

Добавить:

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

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

Ответы [ 3 ]

12 голосов
/ 17 мая 2011

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

Вот почему люди их обескураживают.

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

10 голосов
/ 17 мая 2011

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

Math::sqrRoot(5);

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

6 голосов
/ 18 мая 2011

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

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

$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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...