Статический или не статический метод?

Здравствуйте, наверное глупый вопрос, но недавно задумался над ним. Пишу проект на ларавел, в моделях использую статические методы для получения данных: самые популярные продукты, похожие продукты и тп. И недавно один человек меня спросил: "Почему ты используешь статические методы?", "А почему бы и нет?", - ответил я, ведь они по крайней мере короче, не нужно создавать объект. На что он сказал, что это не комильфо и не ООП и еще что-то невнятное.
А как вы пишите? В чем плюсы/минусы статических/не статических методов?
  • Вопрос задан
  • 8127 просмотров
Решения вопроса 3
@djay
Статика - это глобальное состояние. Статический метод или статическая переменная абсолютно ничем не отличаются от глобальной переменной, потому что, ни статика ни глобальная переменная не были переданны в качестве аргументов нигде и никак, а значит поступают из глобального пространства.

Чем статика может быть опасна?
Представь, что ты пишешь утилиту для загрузки изображений. И вот наступил момент, когда нужно указывать параметры обрезки для превьюшек. Со статикой это может выглядеть так:

public function upload()
{
     $width = Config::read('width');
     $height = Config::read('height');
     // .. Do upload..
}

(На заметку CakePHP кишит такими подходами)
Проблемы такого подхода?

1. Нужно знать и быть точно уверенным, что статичный класс Config, был где-то там далеко инициализирован. А вдруг он не был инициализированным?

2. А что если ты решишь сменить источник конфига? Например читать, это все не из класса `Config` а откуда-нибудь из REST? Придется все переписывать, затем опять тестировать. Эта проблема известна как сильная связка.

3. Попробуй написать юнит тест для такого, без хаков и изращенных костылей. Ведь для того чтобы протестировать этот метод, нам нужно где-то там в глобальном пространстве инициализировать `Config`, затем убедится что он работает.

4. Скрытые зависимости.

Например инициализуруя класс, в случае статики:

$uploader = new Uploader();
$uploader->upload(...);


Ты и твои пользователи не видят какие у класса зависимости и от работы чего вообще он зависит. Проблема заметна особо, когда ты пишешь библиотеку или компонет.

Но тогда почему такие популярные фреймворки как Yii или Laravel полностью покрыты статикой?

Для того чтобы понять какие последствия несет статика, попробуй воспользоватся хоть одним компонентом Yii фреймворка отдельно. Например, если тебе нужна только CAPTCHA ты не сможешь её вытащить оттуда не переписав почти весь компонент, потому что везде внутри присутвует глобальное состояние, в виде `Yii::$app->`. То есть чтобы воспользоватся только капчей, придется подключать весь фреймворк и все его внутренние механизмы, когда это абсолютно не нужно.

Что касается Laravel, то статики там меньше, поскольку некоторые компоненты, вроде Eloquent могут использоватся по отдельности. Статика в ларе, она существует как обёртка, но не как реализация, во многих местах в отличии от Yii.

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

Вообще посмотри, как задачи решаются в Zend / Symfony
Там почти везде все зависимости передаются в качестве аргументов, что есть хорошо, слабо связано, и тестируемо.
Ответ написан
AmdY
@AmdY
PHP и прочие вебштучки
Уже 100500 раз писалось, что в laravel статика ненастоящая это фасад построенный на магическом __callStatic, который создаёт объект или дёргает его из IoC. Просто этакий синтаксический сахар. Потому laravel так легко тестировать и эта псевдосостатика ещё и помогает.
Ответ написан
Комментировать
@matperez
Попробуйте начать тестировать и со временем понятны станут плюсы и минусы статики. Держите их размер под контролем. Если в статической функции используются какие-то сложные/большие компоненты остальной системы, старайтесь передавать их явно в виде параметров. В остальном, у них всего лишь другие цели по сравнению с динамическими методами, они не лучше и не хуже.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы