Домен управляет объектом / классом в laravel - PullRequest
1 голос
/ 23 октября 2019

Я пытаюсь структурировать большое приложение Laravel.

Попытка выяснить:

1) Куда идут объекты бизнес-правил / правил домена?
2) Как выглядят объекты бизнес-правил?

По бизнесуправила я имею в виду правила, как. Данный счет имеет возможные состояния [новый, утвержденный, завершенный]. Только счета в «утвержденном» состоянии могут быть отправлены клиенту по электронной почте. Это упрощенный пример.

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

Этот пост в блоге https://stitcher.io/blog/laravel-beyond-crud-01-domain-oriented-laravel предоставляет структуру приложения, аналогичную моей желаемой структуре приложения. См. Ниже.

app/Domain/Invoices/
    ├── Actions
    ├── QueryBuilders
    ├── Collections
    ├── DataTransferObjects
    ├── Events
    ├── Exceptions
    ├── Listeners
    ├── Models
    ├── Rules
    └── States

Я немного знаком с "теорией" проектирования, основанного на предметной области. Я ищу примеры кода, желательно на Laravel или PHP (другие языки тоже в порядке). Если кто-то может указать мне на проект github / gitlab с примерами кода, которые также были бы хороши.

1 Ответ

0 голосов
/ 23 октября 2019

Сначала я приведу пример, который будет объяснен ниже.

<?php


namespace App;


use RuntimeException;

class Invoice
{
    private const STATUS_NEW = 'new';
    private const STATUS_APPROVED = 'approved';
    private const STATUS_COMPLETED = 'completed';

    /** @var string */
    private $status;

    private function __construct(string $status)
    {
        $this->status = $status;
    }

    public function create(): self
    {
        return new self(self::STATUS_NEW);
    }

    public function approve(): void
    {
        if ($this->status !== self::STATUS_NEW) {
            throw new RuntimeException('Unable to approve invoice, as it is not new');
        }
        $this->status = self::STATUS_APPROVED;
    }

    public function complete(): void
    {
        if ($this->status !== self::STATUS_APPROVED) {
            throw new RuntimeException('Unable to complete invoice, as it is not new');
        }
        $this->status = self::STATUS_COMPLETED;
    }

    public function canBeSentToCustomer(): bool
    {
        return $this->status === self::STATUS_COMPLETED;
    }
}

Итак, за кодом выше есть несколько идей:

  • Имена классов и методовотражать язык домена. Пример: кто-то из продавцов расскажет об утверждении счета-фактуры, что означает $invoice->approve()
  • Класс отвечает за поддержание действительного состояния самостоятельно. Пример: счет-фактура не может быть завершен, если он еще не утвержден
  • Код не заботится о платформах, базах данных, веб-запросах, электронных письмах или html. Все, что нужно сделать, - это реализовать поведение, не беспокоясь о том, откуда поступает ввод или вывод.
...