Я настраиваю себя на неудачу, используя статический метод в Laravel Controller?

Я совершенно новичок в ООП, так что это действительно основной вопрос ООП, в контексте Laravel Controller.

Я пытаюсь создать систему уведомлений, которая создает Notification объекты, когда некоторые другие объекты создаются, редактируются, удаляются и т. д. Так, например, если User отредактировано, то я хочу сгенерировать Notification относительно этого редактирования. Следуя этому примеру, я создал UserObserver что вызывает NotificationController::store() когда User сохраняется

class UserObserver extends BaseObserver
{
public function saved($user)
{
$data = [
// omitted from example
];

NotificationController::store($data);
}
}

Для того, чтобы сделать эту работу, мне пришлось сделать NotificationController::store() статичный.

class NotificationController extends \BaseController {
public static function store($data)
{
// validation omitted from example

$notification = Notification::create($data);
}

Я только смутно знаком с тем, что static значит, скорее всего, с тем, что я здесь делаю, что-то не так, но, похоже, работа выполнена более или менее. Однако все, что я прочитал, указывает на то, что статические функции в общем-то плохая практика То, что я здесь делаю, «неправильно», скажем так? Как я мог сделать это лучше?

У меня будет несколько других классов Observer, которые нужно будет вызывать так же NotificationController::store(), и я хочу NotificationController::store() обрабатывать любую проверку $data,

Я только начинаю узнавать о модульном тестировании. Не затруднит ли то, что я здесь сделал, тестирование?

1

Решение

Я много писал о статике здесь: Как не убить вашу тестируемость с помощью статики. Суть этого применительно к вашему делу заключается в следующем:

Вызовы статических функций пара код. Не возможно замена вызовы статических функций с чем-либо еще или пропускать эти звонки, по любой причине. NotificationController::store() по существу в том же классе вещей, как substr(), Теперь вы, вероятно, не захотите заменить вызов substr чем-нибудь еще; но есть масса причин, по которым вы можете заменить NotificationController, сейчас или позже.

Модульное тестирование — это всего лишь один очевидный случай использования, когда замена очень желательна. Если вы хотите проверить UserObserver::saved функция сама по себе, потому что она содержит сложный алгоритм, который вам нужно проверить со всеми возможными входами, чтобы убедиться, что он работает правильно, вы не можете отделить этот алгоритм от вызова NotificationController::store(), И эта функция в свою очередь, вероятно, вызывает некоторые Model::save() метод, который в свою очередь хочет поговорить с базой данных. Вам нужно настроить всю эту среду, которая требуется для всего этого другого, не связанного с ним кода (и которая может содержать или не содержать собственных ошибок), что по сути невозможно просто протестировать эту функцию самостоятельно.

Если ваш код выглядел больше так:

class UserObserver extends BaseObserver
{
public function saved($user)
{
$data = [
// omitted from example
];

$this->NotificationController->store($data);
}
}

Что ж, $this->NotificationController очевидно, переменная, которая может быть заменена в некоторой точке. Обычно этот объект внедряется в момент создания экземпляра класса:

new UserObserver($notificationController)

Вы можете просто ввести фиктивный объект, который позволяет вызывать любые методы, но который ничего не делает. Тогда вы можете проверить UserObserver::saved() в изоляции и убедитесь, что это на самом деле без ошибок.

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

Предостережение: я никогда не писал ни одной строки кода Laravel, но, насколько я понимаю, это делает поддерживать некоторую форму внедрения зависимости. Если это действительно так, то вам обязательно следует использовать эту возможность. В противном случае помните, какие части вашего кода вы связываете с какими-то другими частями, и как это повлияет на вашу способность разбирать его на части и проводить рефакторинг позже.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]