Обычно делаешь так: пришла новая фича — лезешь в существующий сервис, правишь код, потом ломаешь всё, что работало раньше. Декоратор решает это по-простому: оборачиваешь объект, добавляешь новую логику и оригинальный код не трогаешь.
В Laravel это удобно для сервисов, контроллеров и вообще любых объектов, где нужно расширение функциональности без переписывания всего проекта.
Создание декоратора
Шаг 1: Интерфейс
Создаём интерфейс, чтобы гарантировать, что декоратор и оригинальный объект совпадают по методам:
namespace App\Services;
interface ServiceInterface
{
public function doSomething();
}
Шаг 2: Оригинальный сервис
namespace App\Services;
class OriginalService implements ServiceInterface
{
public function doSomething()
{
return 'Original Service';
}
}
Это тот код, который не трогаем. Любые изменения будут через декораторы.
Шаг 3: Декоратор
namespace App\Services;
class DecoratorService implements ServiceInterface
{
protected $service;
public function __construct(ServiceInterface $service)
{
$this->service = $service;
}
public function doSomething()
{
return $this->service->doSomething() . ' Decorated';
}
}
Класс оборачивает оригинальный сервис и добавляет новую функциональность. Без ковыряния в исходниках.
Использование
В контроллере или другом сервисе создаём объект и оборачиваем его:
namespace App\Http\Controllers;
use App\Services\ServiceInterface;
use App\Services\OriginalService;
use App\Services\DecoratorService;
class SomeController extends Controller
{
public function index(ServiceInterface $service)
{
$originalService = new OriginalService();
$decoratedService = new DecoratorService($originalService);
return $decoratedService->doSomething();
}
}
Результат: Original Service Decorated. Всё. Оригинал целый, новые штуки добавляются через обертку.
Практические моменты
- Цепочка декораторов — можно оборачивать декоратор в другой декоратор, создавая цепочку расширений.
- Интерфейсы реально нужны — без них ты не сможешь подменить реализацию через DI или тестировать классы.
- Контроллеры не знают о внутренностях — только интерфейс. Оригинальный сервис можно менять на мок, декоратор — на другой декоратор, и всё продолжает работать.
Почему это реально удобно
- Расширение функциональности без ломания существующего кода.
- Модульность: каждый декоратор делает одну вещь и не смешивает логику.
- Тестируемость: можно мочь сервисы и декораторы отдельно.
Вывод
Декоратор в Laravel — не магия. Это простая техника, чтобы не ковырять рабочий сервис каждый раз, когда нужен новый функционал. Обернул, добавил метод или изменил поведение — оригинальный код целый, проект живой и масштабируемый.
0 комментариев