В 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 и делать приложения более гибкими и поддерживаемыми.
Добавить комментарий