Skip to content

Commit e538693

Browse files
committed
Added Actions in Library
1 parent d0904d5 commit e538693

File tree

7 files changed

+136
-80
lines changed

7 files changed

+136
-80
lines changed

resources/views/library/actions.blade.php

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
@extends('layout')
22
@section('title', 'Один класс — одна задача')
3-
@section('description', 'Каждый класс в приложении должен отвечать только за одну конкретную задачу или функциональность.')
3+
@section('description', 'Каждый класс в приложении должен отвечать только за одну конкретную задачу.')
44
@section('content')
55

6-
<x-header align="align-items-end">
7-
<x-slot name="sup">Чистота и порядок</x-slot>
6+
<x-header align="align-items-center" image="/img/ui/finger.svg">
7+
<x-slot name="sup">Ясность с первого взгляда</x-slot>
88
<x-slot name="title">Один класс — одна задача</x-slot>
99
<x-slot name="description">
10-
Каждый класс в приложении должен отвечать только за одну конкретную задачу или функциональность.
11-
</x-slot>
12-
<x-slot name="content">
13-
<img src="/img/gusli.svg" class="img-fluid d-block mx-auto">
10+
Каждый класс в приложении должен сосредоточиться на выполнении одной конкретной задачи или функции
1411
</x-slot>
1512
</x-header>
1613

1714
@php
1815
$sections = collect([
1916
'basics',
2017
'focus',
18+
'package',
2119
'conventions',
2220
'tests',
2321
])

resources/views/library/index.blade.php

+21-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<x-container>
1818

1919
<div class="row g-4">
20-
<div class="col-md-6 col-lg-8 mb-4">
20+
<div class="col-md-6 col-lg-8">
2121

2222
<div class="bg-primary bg-opacity-10 rounded p-4 p-xl-5 position-relative overflow-hidden mb-4">
2323
<img src="/img/bird.svg" class="position-absolute w-50 bottom-0 end-0">
@@ -74,7 +74,7 @@ class="link-body-emphasis text-decoration-none icon-link icon-link-hover stretch
7474
</div>
7575
</div>
7676

77-
<div class="col-md-6 col-lg-4 mb-4">
77+
<div class="col-md-6 col-lg-4">
7878
<div class="bg-secondary bg-opacity-10 rounded p-5 h-100 position-relative overflow-hidden">
7979
<img src="/img/sign.svg" class="position-absolute w-100 bottom-0 end-0 d-none d-lg-block">
8080
<ul class="d-grid gap-5 list-unstyled text-balance">
@@ -95,6 +95,25 @@ class="link-body-emphasis text-decoration-none icon-link icon-link-hover stretch
9595

9696
</div>
9797
</div>
98+
99+
100+
<div class="col-md-6 col-lg-4">
101+
<div class="bg-secondary bg-opacity-10 rounded p-5 h-100 position-relative overflow-hidden">
102+
<div class="d-flex flex-column position-relative h-100">
103+
<h3 class="mb-3 fw-bold">Действия</h3>
104+
<p class="mb-auto fw-light">
105+
Класс должен сосредоточиться на выполнении одной конкретной задачи
106+
</p>
107+
108+
<a href="{{ route('library.actions') }}"
109+
class="link-body-emphasis text-decoration-none icon-link icon-link-hover stretched-link mt-4">
110+
Начать читать
111+
<x-icon path="i.arrow-right" class="bi" />
112+
</a>
113+
</div>
114+
</div>
115+
</div>
116+
98117
</div>
99118

100119
</x-container>

storage/library/actions/basics.md

+16-17
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
---
22
title: "Основы"
3-
description: "Что такое принцип 'Один класс — одна задача'?"
3+
description: "Что такое принцип <code>One Class, One Task</code>?"
44
---
55

6-
Принцип «Один класс — одна задача» (One Class, One Task) предполагает, что каждый класс в приложении должен отвечать
7-
только за одну конкретную задачу или функциональность. Это упрощает структуру кода, делает его более понятным и легким
8-
для поддержки. В контексте Laravel этот подход помогает организовать бизнес-логику в виде отдельных классов, которые
9-
выполняют конкретные действия, что позволяет избежать перегруженности классов и улучшает читаемость кода.
10-
11-
Преимущества использования принципа «Один класс — одна задача»:
12-
13-
- **Читаемость кода**: каждый класс отвечает только за одну задачу, что упрощает понимание его назначения и логики.
14-
- **Поддерживаемость**: изменение и тестирование классов становится проще, так как каждый класс содержит только одну
15-
задачу.
16-
- **Изоляция логики**: каждый класс действия изолирован от других частей приложения, что упрощает его тестирование и
17-
поддержку.
18-
- **Повторное использование**: классы действий могут быть повторно использованы в разных частях приложения, что
19-
упрощает разработку и поддержку кода.
20-
- **Улучшение архитектуры**: применение принципа «Один класс — одна задача» помогает улучшить архитектуру вашего
21-
приложения, сделав его более гибким и масштабируемым.
6+
Принцип «Один класс — одна задача» (`One Class, One Task`) устанавливает требование, согласно которому каждый класс в приложении должен выполнять лишь одну конкретную задачу или функциональность. Этот подход способствует созданию более структурированного и предсказуемого кода, а также облегчает его поддержку.
7+
8+
В Laravel это позволяет выделить бизнес-логику в отдельные классы, что освобождает контроллеры и модели от лишних обязанностей и улучшает организацию и читаемость кода.
9+
10+
##### Что это даст?
11+
12+
- **Читаемость кода**: Наличие класса, отвечающего за единую задачу, значительно упрощает понимание его назначения и поведения. Это особенно важно в рамках командной разработки или при возвращении к проекту спустя значительное время, так как открыв класс, разработчик может быстро оценить его функциональность.
13+
14+
- **Простота тестирования**: Изолирование логики в небольшие классы упрощает процесс тестирования. Каждый класс может быть протестирован независимо, что повышает точность и снижает время, необходимое для написания тестов.
15+
16+
- **Снижение сложности**: Логика приложения становится более управляемой, когда она разбивается на мелкие, специализированные части. Такой подход способствует снижению уровня сложности кода и облегчает его восприятие.
17+
18+
- **Легкость изменений**: Внесение изменений в код становится проще, когда изменения касаются небольших классов, каждое из которых отвечает за одну задачу. Это предотвращает возникновение неожиданностей при редактировании, так как изменения в одной части приложения не затрагивают другие компоненты.
19+
20+
Тем не менее, важно сохранять баланс между дроблением логики на мелкие классы и чрезмерной детализацией. Не все аспекты логики следует выносить в отдельные классы, необходимо учитывать контекст.

storage/library/actions/conventions.md

+14-10
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,20 @@ title: "Рекомендуемые соглашения"
33
description: "Помогут вам оставаться последовательными при организации вашего приложения"
44
---
55

6-
**Начните с глагола**
76

8-
Назовите свои классы действий как небольшие явные предложения, начинающиеся с глагола. Например, действие, которое
9-
«отправляет электронное письмо пользователю для сброса пароля», можно назвать `SendResetPasswordEmail`. Такой подход
10-
делает названия классов самодокументированными и легко понятными, что улучшает читабельность кода.
7+
Для упрощения поддержки и организации кода целесообразно придерживаться ряда рекомендаций при создании классов действий.
118

12-
**Используйте папку `Actions`**
9+
##### Начните с глагола
1310

14-
Создайте папку `app/Actions` и сгруппируйте свои действия внутри неё по темам. Это помогает поддерживать структуру
15-
вашего кода организованной и логичной. Например:
11+
Названия классов действий должны представлять собой глаголы, отражающие выполняемую задачу.
12+
13+
Например, если класс предназначен для отправки письма для сброса пароля, его следует назвать `SendResetPasswordEmail`.
14+
15+
16+
##### Используйте директорию `Actions`
17+
18+
Создайте папку `app/Actions` и сгруппируйте свои действия внутри неё по модулям.
19+
Это поможет поддерживать структуру вашего кода организованной и логичной. Например:
1620

1721
```php
1822
app/
@@ -41,8 +45,8 @@ app/
4145
└── ...
4246
```
4347

44-
В качестве альтернативы, если ваше приложение уже разделено на темы — или модули — вы можете создать папку `Actions` под
45-
каждым из этих модулей. Например:
48+
Если ваше приложение уже разделено на модули - создайте директорию `Actions` в
49+
каждом из них:
4650

4751
```php
4852
app/
@@ -59,4 +63,4 @@ app/
5963
└── ...
6064
```
6165

62-
Такая организация помогает вам поддерживать порядок в коде и упрощает его навигацию.
66+
Такая организация поможет вам поддерживать порядок в коде и упростит навигацию.

storage/library/actions/focus.md

+4-44
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
---
22
title: "Фокус на работе приложения"
3-
description: "Что такое принцип 'Один класс — одна задача'?"
3+
description: "Использование <code>Actions</code> позволяет сосредоточиться на бизнес-логике приложения, а не на технических деталях."
44
---
55

6-
Использование `Actions` позволяет сосредоточиться на бизнес-логике приложения, а не на технических деталях.
76
Классы `Action` выполняют конкретные задачи и изолируют их от других частей приложения, что упрощает понимание кода и
87
его поддержку. Логика, связанная с выполнением одной задачи, собирается в одном месте, что облегчает её изменение и тестирование.
98

9+
Пример класса действия:
1010

1111
```php
1212
class GenerateReservationCode
@@ -29,49 +29,9 @@ class GenerateReservationCode
2929
}
3030
```
3131

32-
Это позволит вам вызывать объект класса, как если бы он был функцией. Например:
32+
Данный класс можно вызвать как функцию:
33+
3334
```php
3435
$generator = new GenerateReservationCode();
3536
$reservationCode = $generator(8); // Генерация кода длиной 8 символов
3637
```
37-
38-
39-
В это системе Laravel есть прекрасный пакет `Laravel Actions` — это пакет, который предлагает новый способ организации
40-
логики вашего Laravel-приложения, сосредоточив внимание на действиях, которые выполняет ваше приложение. Вместо создания
41-
контроллеров, джобов, слушателей и других элементов, этот пакет позволяет создавать PHP-классы, каждый из которых
42-
выполняет одну конкретную задачу. Эти классы можно запускать как угодно: из контроллеров, консольных команд, событий и
43-
так далее.
44-
45-
```php
46-
class GenerateReservationCode
47-
{
48-
use AsAction;
49-
50-
const UNAMBIGUOUS_ALPHABET = 'BCDFGHJLMNPRSTVWXYZ2456789';
51-
52-
public function handle(int $characters = 7): string
53-
{
54-
do {
55-
$code = $this->generateCode($characters);
56-
} while(Reservation::where('code', $code)->exists());
57-
58-
return $code;
59-
}
60-
61-
protected function generateCode(int $characters): string
62-
{
63-
return substr(str_shuffle(str_repeat(static::UNAMBIGUOUS_ALPHABET, $characters)), 0, $characters);
64-
}
65-
}
66-
```
67-
68-
и вызывать его так:
69-
```php
70-
GenerateReservationCode::run() // Генерация кода длиной 7 символов
71-
```
72-
73-
> **Примечание** Вы можете узнать больше об удобстве использование действий с пакетом `Laravel Actions` на его [официальном сайте](https://laravelactions.com/).
74-
75-
Но вам не обязательно использовать пакет, чтобы следовать принципу «Один класс — одна задача». Вы можете создавать свои
76-
собственные классы действий, используя стандартные средства Laravel/PHP. Важно помнить, что главная цель — разделить логику
77-
вашего приложения на небольшие, легко понимаемые и поддерживаемые части.

storage/library/actions/package.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
title: "Пакет Laravel Actions"
3+
description: "Действие можно удобно запустить как объект, контроллер, фоновую задачу и консольную команду."
4+
---
5+
6+
В экосистеме Laravel есть прекрасный пакет `Laravel Actions` который способствует организации кода вокруг действий.
7+
Данный пакет позволяет создавать классы действий, которые могут быть вызваны в различных контекстах, таких как контроллеры, события и консольные команды.
8+
Это обеспечивает более универсальный и гибкий код.
9+
10+
11+
Пример использования:
12+
13+
```php
14+
class GenerateReservationCode
15+
{
16+
use AsAction;
17+
18+
const UNAMBIGUOUS_ALPHABET = 'BCDFGHJLMNPRSTVWXYZ2456789';
19+
20+
public function handle(int $characters = 7): string
21+
{
22+
do {
23+
$code = $this->generateCode($characters);
24+
} while(Reservation::where('code', $code)->exists());
25+
26+
return $code;
27+
}
28+
29+
protected function generateCode(int $characters): string
30+
{
31+
return substr(str_shuffle(str_repeat(static::UNAMBIGUOUS_ALPHABET, $characters)), 0, $characters);
32+
}
33+
}
34+
```
35+
36+
Класс можно вызвать следующим образом:
37+
38+
```php
39+
GenerateReservationCode::run()
40+
```
41+
42+
Если вам нужно выполнить действие в очереди, то вы так же можете это сделать, например:
43+
44+
```php
45+
GenerateReservationCode::dispatch();
46+
```
47+
48+
> **Примечание** Вы можете узнать больше об удобстве использование действий с пакетом `Laravel Actions` на его [официальном сайте](https://laravelactions.com/).
49+

storage/library/actions/tests.md

+27
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,30 @@ description: "Что такое принцип 'Один класс — одна
55

66
Поскольку каждый `Action` отвечает за одну задачу, его тестирование становится более простым и эффективным.
77
Вы можете изолировать и протестировать каждое действие отдельно, что упрощает написание и выполнение тестов.
8+
9+
```php
10+
class GenerateReservationCodeTest extends TestCase
11+
{
12+
public function testGeneratedCodeContainsOnlyAllowedCharacters(): void
13+
{
14+
$code = GenerateReservationCode::run(8);
15+
16+
$this->assertMatchesRegularExpression(
17+
'/^[BCDFGHJLMNPRSTVWXYZ2456789]+$/',
18+
$code
19+
);
20+
}
21+
22+
public function testGeneratedCodeIsUrlSafe(): void
23+
{
24+
$code = GenerateReservationCode::run();
25+
26+
$this->assertTrue(
27+
filter_var($code, FILTER_VALIDATE_URL) === false
28+
);
29+
}
30+
}
31+
```
32+
33+
А наличие четко определенных входных и выходных данных позволят легко
34+
обнаруживать и исправлять ошибки.

0 commit comments

Comments
 (0)