5 советов по написанию кода Laravel

Мы составили 5 простых советов по написанию кода в Laravel, следуя которым можно улучшить читаемость кода и его качество. Данные советы подходят под любую версию Laravel.

1. Принцип единой ответственности

Принцип единой ответственности или Single responsibility principle, означает что каждый класс должен иметь только одну обязанность. Не нужно в одном классе делать много разных вещей, старайтесь чтобы один класс делал только одно дело.

Плохо:

public function update(Request $request): string
{
    $validated = $request->validate([
        'title' => 'required|max:255',
        'events' => 'required|array:date,type'
    ]);

    foreach ($request->events as $event) {
        $date = $this->carbon->parse($event['date'])->toString();

        $this->logger->log('Update event ' . $date . ' :: ' . $);
    }

    $this->event->updateGeneralEvent($request->validated());

    return back();
}

Хорошо:

public function update(UpdateRequest $request): string
{
    $this->logService->logEvents($request->events);

    $this->event->updateGeneralEvent($request->validated());

    return back();
}

2. Методы должны делать что-то одно

Старайтесь чтобы функция или метод класса делал что-то одно и делал это хорошо.

Плохо:

public function getFullNameAttribute(): string
{
    if (auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified()) {
        return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name;
    } else {
        return $this->first_name[0] . '. ' . $this->last_name;
    }
}

Хорошо:

public function getFullNameAttribute(): string
{
    return $this->isVerifiedClient() ? $this->getFullNameLong() : $this->getFullNameShort();
}

public function isVerifiedClient(): bool
{
    return auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified();
}

public function getFullNameLong(): string
{
    return 'Mr. ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name;
}

public function getFullNameShort(): string
{
    return $this->first_name[0] . '. ' . $this->last_name;
}

3. Пишите тонкие контроллеры и толстые модели

Контроллер должен быть максимально простым и маленьким, чтобы можно было быстро понять какую задачу он решает. Если нужно, то выносите работу с данными в модели (если работаете с запросами в базу данных).

Плохо:

public function index()
{
    $clients = Client::verified()
        ->with(['orders' => function ($q) {
            $q->where('created_at', '>', Carbon::today()->subWeek());
        }])
        ->get();

    return view('index', ['clients' => $clients]);
}

Хорошо:

public function index()
{
    return view('index', ['clients' => $this->client->getWithNewOrders()]);
}

class Client extends Model
{
    public function getWithNewOrders(): Collection
    {
        return $this->verified()
            ->with(['orders' => function ($q) {
                $q->where('created_at', '>', Carbon::today()->subWeek());
            }])
            ->get();
    }
}

4. Валидация

Используйте к каждому контроллеру свои Request классы, следуя принципам тонкого контроллера и SRP (single responsibilite principle — принципу единой ответственности), выносите валидацию из контроллера в Request классы.

Плохо:

public function store(Request $request)
{
    $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
        'publish_at' => 'nullable|date',
    ]);

    // ...
}

Хорошо:

public function store(PostRequest $request)
{
    // ...
}

class PostRequest extends Request
{
    public function rules(): array
    {
        return [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
            'publish_at' => 'nullable|date',
        ];
    }
}

5. Храните всю бизнес логику в сервисах

Запомните, контроллер должен выполнять только свои прямые обязанности, поэтому выносите всю бизнес логику в отдельные классы (их называют сервисы).

Плохо:

public function store(Request $request)
{
    if ($request->hasFile('image')) {
        $request->file('image')->move(public_path('images') . 'temp');
    }
    
    // ...
}

Хорошо:

public function store(Request $request)
{
    $this->articleService->handleUploadedImage($request->file('image'));

    // ...
}

class ArticleService
{
    public function handleUploadedImage($image): void
    {
        if (!is_null($image)) {
            $image->move(public_path('images') . 'temp');
        }
    }
}

Вот и все 5 советов для того чтобы улучшить читаемость и качество кода. В следующей статье мы еще расскажем другие интересные вещи по Laravel, которые сделают вашу деятельность лучше и правильнее.

Запись опубликована в рубрике Laravel с метками , , , . Добавьте в закладки постоянную ссылку.

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