Go to file
Ваше Имя e7d0f9d7b3 Добавил тестов 2025-07-20 19:46:35 +05:00
.github/workflows first commit 2025-07-20 19:34:37 +05:00
app first commit 2025-07-20 19:34:37 +05:00
bootstrap first commit 2025-07-20 19:34:37 +05:00
config first commit 2025-07-20 19:34:37 +05:00
database first commit 2025-07-20 19:34:37 +05:00
modules first commit 2025-07-20 19:34:37 +05:00
public first commit 2025-07-20 19:34:37 +05:00
resources first commit 2025-07-20 19:34:37 +05:00
routes first commit 2025-07-20 19:34:37 +05:00
storage first commit 2025-07-20 19:34:37 +05:00
tests Добавил тестов 2025-07-20 19:46:35 +05:00
.editorconfig first commit 2025-07-20 19:34:37 +05:00
.env.example first commit 2025-07-20 19:34:37 +05:00
.gitattributes first commit 2025-07-20 19:34:37 +05:00
.gitignore first commit 2025-07-20 19:34:37 +05:00
.styleci.yml first commit 2025-07-20 19:34:37 +05:00
CHANGELOG.md first commit 2025-07-20 19:34:37 +05:00
README.md Добавил тестов 2025-07-20 19:46:35 +05:00
artisan first commit 2025-07-20 19:34:37 +05:00
composer.json first commit 2025-07-20 19:34:37 +05:00
composer.lock first commit 2025-07-20 19:34:37 +05:00
package.json first commit 2025-07-20 19:34:37 +05:00
phpunit.xml first commit 2025-07-20 19:34:37 +05:00
vite.config.js first commit 2025-07-20 19:34:37 +05:00

README.md

Пример приложения

В данном примере веб-интерфейс отсутствует, функционал можно протестить юнит-тестами.

Тесты в папке ./tests

Запуск тестов:

Все тесты

php artisan test

Только юнит-тесты

php artisan test --testsuite=Unit

Конкретный тест

php artisan test tests/Unit/UserTest.php

С покрытием кода

php artisan test --coverage

Модули приложения

Код разделен на модули. Позволит проще распараллелить задачи между несколькими разработчиками. Позволит переиспользовать готовые модули в разных проектах.

Модули в папке ./modules Подробней

В результате получаем

① Контроль над SQL-запросами

Проблема Eloquent:

  • Генерирует сложные SQL, которые трудно оптимизировать
  • N+1 проблема (ленивая загрузка отношений)

Решение:

public function getList(int $limit, int $offset, array $dsl = []): array 
{
    $data = $this->tasksQuery->select($dsl)->limit($limit, $offset)->all();
    // ...
}

Преимущества:

  • Явный контроль над запросами через TasksQuery
  • Четкое разделение на простые запросы (select(), limit())
  • Нет "магии", которую трудно дебажить

② Производительность

Проблема Eloquent:

  • Гибертность моделей (каждая сущность — объект с оверхедом)
  • Проблемы с большими выборками

Решение:

private function receiveAdditionalData(array &$data, array $dsl): void
{
    if (in_array('options', $dsl)) {
        $tasksIds = $this->pluck('id', $data);
        $otherData = $this->otherQuery->getForTasks($tasksIds); // Один запрос для всех задач
        // ...
    }
}

Преимущества:

  • Работа с массивами вместо объектов (меньше потребление памяти)
  • Явная загрузка связанных данных за 1 запрос (не N+1)

③ Тестируемость

Проблема Eloquent:

  • Трудно мокировать (глобальные scope, трейты)
  • Зависимость от статики (DB::shouldReceive)

Решение:

public function setTasksQuery(TasksQuery $query): void {
    $this->tasksQuery = $query; // Легко подменить mock-объектом
}

Преимущества:

  • Чистые зависимости (интерфейсы или конкретные классы)
  • Проще писать unit-тесты

④ Гибкость архитектуры

Проблема Eloquent:

  • Жесткая привязка к ActiveRecord
  • Сложно разделить на слои (логика в моделях)

Ваше решение:

class TasksStorage {
    // Слой хранилища
    private TasksQuery $tasksQuery; // Отдельный класс для запросов
    private OtherQuery $otherQuery; // Отдельный класс для связей
}

Преимущества:

  • Четкое разделение:
    • TasksQuery — построение SQL
    • TasksStorage — бизнес-логика доступа к данным
    • DTO — передача данных между слоями

3. Наглядное сравнение

Критерий Eloquent Данный подход
Производительность Низкая (N+1, оверхед) Высокая (оптимизированные запросы)
Тестируемость Сложная Простая (DI)
Контроль SQL Ограниченный Полный
Поддержка Легкая для простых проектов Лучше для сложных систем

Данный подход — это "прозрачность и контроль", где:

  • Каждая операция предсказуема
  • Легко оптимизировать под нагрузку
  • Архитектура готова к масштабированию