В PHP (и других языках программирования) классы с суффиксами Handler и Action часто используются для организации логики приложения. Они могут взаимодействовать друг с другом, и их использование часто связано с определенными паттернами проектирования. Давайте разберем, как они могут взаимодействовать и какие паттерны при этом применяются.
1. Классы Handler
Классы с суффиксом Handler обычно отвечают за обработку определенных задач, событий или запросов. Они часто используются для централизованного управления логикой, например:
- Обработка HTTP-запросов.
- Управление событиями.
- Обработка ошибок.
- Работа с внешними сервисами.
Пример:
class UserRegistrationHandler {
public function handle(User $user) {
// Логика регистрации пользователя
$this->validateUser($user);
$this->saveUser($user);
$this->sendWelcomeEmail($user);
}
private function validateUser(User $user) { /* ... */ }
private function saveUser(User $user) { /* ... */ }
private function sendWelcomeEmail(User $user) { /* ... */ }
}2. Классы Action
Классы с суффиксом Action обычно представляют собой небольшие, атомарные задачи, которые выполняют конкретное действие. Они часто используются в рамках паттерна Command (Команда) или Action-Domain-Responder (ADR).
Пример:
class SendWelcomeEmailAction {
public function execute(User $user) {
// Логика отправки email
$email = new Email($user->email, 'Welcome!', 'Thank you for registering.');
$email->send();
}
}3. Взаимодействие Handler и Action
Классы Handler могут использовать классы Action для выполнения конкретных задач. Это позволяет разделить ответственность и сделать код более модульным.
Пример:
class UserRegistrationHandler {
private $sendWelcomeEmailAction;
public function __construct(SendWelcomeEmailAction $sendWelcomeEmailAction) {
$this->sendWelcomeEmailAction = $sendWelcomeEmailAction;
}
public function handle(User $user) {
$this->validateUser($user);
$this->saveUser($user);
$this->sendWelcomeEmailAction->execute($user); // Используем Action
}
private function validateUser(User $user) { /* ... */ }
private function saveUser(User $user) { /* ... */ }
}Здесь:
UserRegistrationHandlerотвечает за общую логику регистрации.SendWelcomeEmailActionотвечает за конкретную задачу (отправку email).
4. Паттерны, связанные с Handler и Action
a. Command (Команда)
Паттерн Command инкапсулирует запрос как объект, позволяя параметризовать клиентов с различными запросами, ставить запросы в очередь или поддерживать отмену операций. Классы Action часто реализуют этот паттерн.
Пример:
interface Command {
public function execute();
}
class SendWelcomeEmailAction implements Command {
private $user;
public function __construct(User $user) {
$this->user = $user;
}
public function execute() {
// Логика отправки email
}
}
// Использование
$action = new SendWelcomeEmailAction($user);
$action->execute();b. Chain of Responsibility (Цепочка обязанностей)
Паттерн Chain of Responsibility позволяет передавать запрос по цепочке обработчиков (Handler). Каждый обработчик решает, может ли он обработать запрос, или передает его следующему обработчику.
Пример:
abstract class Handler {
private $nextHandler;
public function setNext(Handler $handler): Handler {
$this->nextHandler = $handler;
return $handler;
}
public function handle(Request $request) {
if ($this->nextHandler) {
return $this->nextHandler->handle($request);
}
return null;
}
}
class AuthHandler extends Handler {
public function handle(Request $request) {
if (!$request->isAuthenticated()) {
throw new Exception('Not authenticated');
}
return parent::handle($request);
}
}
class LoggingHandler extends Handler {
public function handle(Request $request) {
// Логирование запроса
return parent::handle($request);
}
}
// Использование
$chain = new AuthHandler();
$chain->setNext(new LoggingHandler());
$chain->handle($request);c. Action-Domain-Responder (ADR)
ADR — это паттерн, который разделяет приложение на три компонента:
- Action: Обрабатывает запрос и вызывает Domain.
- Domain: Содержит бизнес-логику.
- Responder: Формирует ответ.
Пример:
class UserRegistrationAction {
private $userRepository;
public function __construct(UserRepository $userRepository) {
$this->userRepository = $userRepository;
}
public function __invoke(Request $request, Response $response) {
$user = new User($request->get('email'));
$this->userRepository->save($user);
return $response->withStatus(201);
}
}5. Когда использовать Handler и Action
Handler: Используйте для классов, которые управляют сложной логикой или координируют выполнение нескольких задач.Action: Используйте для классов, которые выполняют одну конкретную задачу (например, отправка email, сохранение данных).
6. Преимущества
- Разделение ответственности: Логика разделена между классами, что упрощает поддержку и тестирование.
- Гибкость: Классы
Actionможно легко переиспользовать в разныхHandler. - Читаемость: Код становится более понятным и структурированным.
7. Итог
Таким образом, Handler и Action — это мощные инструменты для организации кода, которые помогают следовать принципам SOLID и делать приложения более гибкими и поддерживаемыми.


Добавить комментарий