Работали ли вы с абстрактными классами для задач (например, Abstract Job)?

«Работали ли вы с абстрактными классами для задач (например, Abstract Job)?» — вопрос из категории Паттерны, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, работал с подобными абстракциями, в основном в контексте фоновых заданий (jobs) и очередей. В Laravel это не абстрактный класс Job, а интерфейс ShouldQueue и трейты для создания задач, помещаемых в очередь.

Типичная реализация job в Laravel:

<?php

namespace AppJobs;

use AppModelsPodcast;
use IlluminateBusQueueable;
use IlluminateContractsQueueShouldQueue;
use IlluminateFoundationBusDispatchable;
use IlluminateQueueInteractsWithQueue;
use IlluminateQueueSerializesModels;

class ProcessPodcast implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(
        public Podcast $podcast // Модель будет автоматически сериализована
    ) {}

    public function handle(): void
    {
        // Основная логика задачи
        $this->podcast->processAudio();
        $this->podcast->notifySubscribers();
    }

    public function failed(Throwable $exception): void
    {
        // Обработка неудачи задачи
        $this->podcast->update(['processing_status' => 'failed']);
    }
}

Ключевые компоненты и опыт:

  • Dispatchable: Позволяет отправлять задачу в очередь простым вызовом ProcessPodcast::dispatch($podcast).
  • SerializesModels: Корректно сериализует и восстанавливает модели Eloquent при выполнении задачи.
  • InteractsWithQueue: Дает контроль над самой задачей (например, $this->delete(), $this->release(60) для повторной попытки).
  • Обработка ошибок: Всегда реализую метод failed() для логирования и изменения состояния системы при критических сбоях.
  • Паттерн Command/Handler: Такая реализация job — это практическое применение паттерна Command, где задача инкапсулирует запрос на выполнение действия.