Введение в слой приложения. Предметно-ориентированный Laravel

Еще в главе 1 я утверждал, что одной из характеристик доменно-ориентированных проектов Laravel является следующее:

[ … ] самое важное, что вы начинаете думать в группах связанных бизнес-концепций, а не в группах кода с одинаковыми техническими свойствами.

Другими словами: сгруппируйте свой код на основе того, что он напоминает в реальном мире, а не его назначения в базе кода.

Все статьи серии

Предметно-ориентированный Laravel

Я также написал, что доменный слой и слой приложения – это две разные вещи. Кроме того, слою приложения разрешается использовать сразу несколько доменов, т.к. приложение нуждается в предоставлении функциональности домена конечному пользователю.

Но что именно относится к этому слою приложения? Как нам сгруппировать код там? На эти вопросы мы ответим в этой главе.

Мы входим в слой приложения. Добро пожаловать!

Несколько приложений

Первое, что важно понять, это то, что один проект может иметь несколько приложений. На самом деле, каждый проект Laravel уже имеет два приложения по умолчанию: HTTP – и консольные приложения. Тем не менее, есть еще несколько частей вашего проекта, которые можно рассматривать как отдельное приложение: каждая сторонняя интеграция, REST API, фронтальный клиентский портал, бэкенд администратора и что-то еще.

Все это можно рассматривать как отдельные приложения, раскрывающие и представляющие домен для своих собственных уникальных вариантов использования. На самом деле, я склонен думать о консоли artisan как еще об одном приложении в этом списке: это приложение, используемое разработчиками для работы с проектом и манипулирования им.

Поскольку мы занимаемся веб-разработкой, наше основное внимание, вероятно, будет сосредоточено на приложениях, связанных с HTTP. Так что же в них входит? Давайте посмотрим:

  • Контроллеры
  • Реквесты
  • Правила валидации для конкретных приложений
  • Middleware
  • Ресурсы
  • Представления
  • QueryBuilders

Я бы даже сказал, что bade-представления, JavaScript и CSS-файлы принадлежат приложению и не должны быть отложены в папку resources. Я понимаю, что это слишком далеко для многих людей, но я хотел бы упомянуть об этом, по крайней мере.

Помните, что цель приложения-получить входные данные пользователя, передать их в домен и представить выходные данные удобным для пользователя способом. После нескольких глав, посвященных коду предметной области, неудивительно, что большая часть кода приложения-это просто структурный, часто скучный код; передача данных из одной точки в другую.

Тем не менее, есть много чего рассказать о нескольких концепциях, упомянутых выше: ViewModels, сторонние интеграции, а как насчет рабочих мест? Мы рассмотрим эти темы в следующих статьях, но пока мы хотим сосредоточиться на основных идеях, лежащих в основе слоя приложения.

Структурирование HTTP-приложений

Есть один очень важный момент, который мы должны обсудить, прежде чем двигаться дальше: как вообще будет структурировано HTTP-приложение? Должны ли мы следовать условностям Laravel или нам нужно еще немного подумать?

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

App/Admin
├── Http
│   ├── Controllers
│   ├── Kernel.php
│   └── Middleware
├── Requests
├── Resources
├── Rules
└── ViewModels

Эта структура хороша в небольших проектах, но, честно говоря, она не очень хорошо масштабируется. Чтобы прояснить, что я имею в виду, я покажу вам структуру документа административного приложения в одном из наших клиентских проектов. Очевидно, я не могу раскрыть слишком много информации об этом проекте, поэтому я вычеркнул большинство имен классов. Я выделил некоторые классы, связанные со счетом-фактурой в приложении администратора, которые мы уже изучали в прошлых главах. Давайте взглянем!

О счастливая прокрутка!

App/Admin
├── Controllers
│   ├── █████████
│   │   ├── ███████████████████.php
│   │   ├── ████████████████████████████████.php
│   │   ├── ███████████████████████.php
│   │   ├── ██████████████████████████████████.php
│   │   ├── ███████████████████████.php
│   │   ├── █████████████████████████.php
│   │   ├── ███████████████████████.php
│   │   ├── ███████████████████████████████.php
│   │   ├── ██████████████████.php
│   │   └── ████████████████.php
│   ├── ████████████
│   │   ├── ████████████████████████████████.php
│   │   ├── ████████████████
│   │   │   ├── ████████████████████████████████.php
│   │   │   ├── █████████████████████████████████████████.php
│   │   │   ├── ██████████████████████████████.php
│   │   │   ├── ████████████████████████████████.php
│   │   │   ├── ███████████████████████████████.php
│   │   │   └── ████████████████████████████████.php
│   │   ├── █████████████████████████████████.php
│   │   ├── ██████████████████████████████████.php
│   │   ├── █████████████████████████████████.php
│   │   ├── ██████████████████████████████.php
│   │   ├── █████████████████████████████.php
│   │   ├── █████████████████████████████████████████.php
│   │   ├── █████████████████████████████████████.php
│   │   ├── ██████████████████████████████████.php
│   │   ├── █████████████████████████████████████████.php
│   │   ├── ████████████████████████████████████.php
│   │   ├── █████████████
│   │   │   ├── █████████████████████████████.php
│   │   │   ├── ███████████████████████████.php
│   │   │   ├── █████████████████████████████.php
│   │   │   ├── ███████████████████████████████████████████.php
│   │   │   ├── ███████████████████████████████████████.php
│   │   │   ├── ████████████████████████████.php
│   │   │   └── █████████████████████████████.php
│   │   ├── ██████████████████████████████.php
│   │   └── █████████████████████████.php
│   ├── ███
│   │   ├── ████████████████████.php
│   │   ├── ██████████████████████.php
│   │   ├── █████████████████████.php
│   │   ├── █████████████.php
│   │   ├── █████████████████████.php
│   │   ├── ██████████████████.php
│   │   ├── ██████████████████.php
│   │   ├── ██████████████████████.php
│   │   ├── ██████████████████████.php
│   │   ├── ███████████████████.php
│   │   ├── ████████████████████.php
│   │   ├── ██████████████████.php
│   │   ├── ██████████████████████████.php
│   │   ├── ████████████████████.php
│   │   ├── ██████████████████.php
│   │   └── ████████████████.php
│   ├── ███████████████████.php
│   ├── █████████████████████.php
│   ├── ████████████
│   │   ├── ███████████████████████.php
│   │   ├── ██████████████████.php
│   │   ├── ████████████████████.php
│   │   ├── ████████████████████.php
│   │   ├── ████████████████████████
│   │   │   ├── █████████████████████████████████████████.php
│   │   │   ├── ██████████████████████████████████████.php
│   │   │   ├── █████████████████████████████████.php
│   │   │   ├── ██████████████████████████████.php
│   │   │   ├── ███████████████████████████████.php
│   │   │   ├── ███████████████████████████████████████.php
│   │   │   ├── ███████████████████████████████.php
│   │   │   ├── ████████████████████████████████████████.php
│   │   │   └── █████████████████████████████████████.php
│   │   ├── Invoices
│   │   │   ├── ████████████████████████████████████.php
│   │   │   ├── █████████████████████.php
│   │   │   ├── IgnoreMissedInvoicesController.php
│   │   │   ├── ██████████████████████.php
│   │   │   ├── ████████████████████.php
│   │   │   ├── InvoiceStatusController.php
│   │   │   ├── InvoicesController.php
│   │   │   ├── MissedInvoicesController.php
│   │   │   ├── ████████████████████████.php
│   │   │   └── RefreshMissedInvoicesController.php
│   │   ├── ████████
│   │   │   └── █████████████████████.php
│   │   ├── ██████████████████.php
│   │   └── ██████████████████.php
│   ├── ███████████████████
│   │   ├── ████████████████████████.php
│   │   ├── ████████████████████████████.php
│   │   ├── ███████████████████.php
│   │   ├── ████████████████████.php
│   │   ├── ████████████████████.php
│   │   ├── ██████████████████████████.php
│   │   ├── ███████████████████████████.php
│   │   ├── ██████████████████████████████████.php
│   │   ├── ███████████████████████████████████.php
│   │   ├── ██████████████████████████.php
│   │   ├── ███████████████████████████████.php
│   │   ├── ████████████████████████████████.php
│   │   ├── ████████████████████████.php
│   │   ├── ████████████████████████.php
│   │   ├── █████████████████████.php
│   │   ├── ██████████████████████████.php
│   │   ├── ██████████████████████████████.php
│   │   ├── ██████████████████████████.php
│   │   ├── ███████████████████████.php
│   │   ├── ██████████████████████.php
│   │   ├── ████████████████████████████.php
│   │   ├── ███████████████████████.php
│   │   ├── █████████████████████████████.php
│   │   ├── ██████████████████████.php
│   │   ├── ███████████████████████████████.php
│   │   ├── ███████████████████████.php
│   │   ├── ███████████████████████.php
│   │   ├── ███████████████████████████████.php
│   │   ├── ████████████████████████.php
│   │   ├── ██████████████████████████████.php
│   │   ├── ███████████████████████████████.php
│   │   ├── █████████████████████████.php
│   │   ├── ██████████████████████.php
│   │   ├── ███████████████████████████.php
│   │   ├── █████████████████████████████████.php
│   │   ├── ███████████████████████████.php
│   │   ├── ████████████████████████████.php
│   │   ├── ████████████████████.php
│   │   └── ███████████████.php
│   ├── ███████████████.php
│   ├── ███████████████.php
│   ├── █████████████
│   │   ├── █████████████████████.php
│   │   ├── █████████████████████████████.php
│   │   ├── ████████████████████████████.php
│   │   ├── ███████████████████████████.php
│   │   ├── ██████████████████████████.php
│   │   ├── ██████████████████████████.php
│   │   └── █████████████████████████.php
│   ├── ██████████████████.php
│   ├── █████████████████.php
│   ├── █████████████████████████.php
│   ├── ██████████████████████.php
│   ├── ████████
│   │   ├── ███████████████████.php
│   │   ├── ███████████████████████████.php
│   │   ├── █████████████████████.php
│   │   └── █████████████████.php
│   ├── ███████████████
│   │   ├── █████████████████.php
│   │   ├── ███████████████.php
│   │   ├── ██████████████.php
│   │   ├── ████████████████████████.php
│   │   ├── ██████████████████████████.php
│   │   ├── ██████████████████████████.php
│   │   └── ███████████████████.php
│   ├── ████████████████████.php
│   ├── ██████████
│   │   ├── ███████████████████████████.php
│   │   ├── ██████████████████.php
│   │   ├── ███████████████████.php
│   │   ├── ███████████████.php
│   │   ├── ████████████████████████.php
│   │   ├── █████████████████████████████.php
│   │   ├── ████████████████████████.php
│   │   ├── █████████████████████.php
│   │   ├── ████████████████████.php
│   │   ├── ████████████████████████.php
│   │   ├── ████████████████████████████.php
│   │   ├── ███████████████████████.php
│   │   ├── ███████████████████.php
│   │   ├── ███████████████████████.php
│   │   ├── ████████████████.php
│   │   ├── ██████████████████.php
│   │   ├── █████████████████.php
│   │   ├── ██████████████████.php
│   │   ├── █████████████████████████████.php
│   │   ├── ██████████████████████.php
│   │   ├── ████████████████████.php
│   │   ├── ████████████████████████.php
│   │   ├── ███████████████████.php
│   │   ├── ███████████████.php
│   │   └── ██████████████████.php
│   ├── ███████
│   │   └── ████████████████.php
│   └── ███████████████.php
├── Filters
│   ├── ████████████████████.php
│   ├── ███████████████████████████.php
│   ├── █████████████████████████.php
│   ├── ██████████████████████████████████.php
│   ├── ██████████████████████.php
│   ├── █████████████████████████████.php
│   ├── ██████████████████████████.php
│   ├── ████████████████.php
│   ├── ███████████.php
│   ├── ███████████.php
│   ├── ████████████████.php
│   ├── InvoiceMonthFilter.php
│   ├── InvoiceOfferFilter.php
│   ├── InvoiceStatusFilter.php
│   ├── InvoiceYearFilter.php
│   ├── █████████████████████.php
│   ├── ███████████.php
│   └── ███████████████████.php
├── Middleware
│   ├── ██████████████████████████.php
│   ├── █████████████████████.php
│   ├── █████████████████████████████████.php
│   ├── █████████████████████████████████████.php
│   ├── EnsureValidHabitantInvoiceCollectionSettingsMiddleware.php
│   ├── EnsureValidInvoiceDraftSettingsMiddleware.php
│   ├── ██████████████████████████████████.php
│   ├── EnsureValidOwnerInvoiceCollectionSettingsMiddleware.php
│   ├── ██████████████████████.php
│   ├── █████████████████████.php
│   ├── █████████████████████████████.php
│   ├── █████████████████████████████████.php
│   ├── ████████████████████.php
│   ├── ███████████████████.php
│   └── █████████████████.php
├── Queries
│   ├── ██████████████████.php
│   ├── ███████████████████████████.php
│   ├── ██████████████████.php
│   ├── ████████████████████████.php
│   ├── ██████████████████████.php
│   ├── ██████████████████.php
│   ├── ██████████████████████.php
│   ├── ███████████████████.php
│   ├── ████████████████████████.php
│   ├── █████████████████████████████.php
│   ├── ████████████████████████.php
│   ├── ████████████████████.php
│   ├── █████████████████████.php
│   ├── ███████████████████.php
│   ├── ████████████████████.php
│   ├── █████████████████████████.php
│   ├── ██████████████████████.php
│   ├── ███████████████████████.php
│   ├── ██████████████████.php
│   ├── ██████████████████████████████████.php
│   ├── ███████████████████████████.php
│   ├── █████████████████████.php
│   ├── InvoiceCollectionIndexQuery.php
│   ├── InvoiceIndexQuery.php
│   ├── █████████████████████████████.php
│   ├── ███████████████████████.php
│   ├── ███████████████.php
│   ├── ████████████████████████████.php
│   ├── ████████████████████████.php
│   ├── ██████████████████.php
│   ├── █████████████████████.php
│   ├── █████████████████████████████.php
│   ├── ████████████████████.php
│   ├── ████████████████.php
│   ├── ██████████████████.php
│   ├── █████████████████████████.php
│   ├── ████████████████████████.php
│   ├── █████████████████████.php
│   ├── ██████████████████.php
│   ├── ███████████████████.php
│   ├── ███████████████.php
│   └── ███████████████.php
├── Requests
│   ├── █████████████████████████.php
│   ├── █████████████████████.php
│   ├── ██████████████.php
│   ├── ██████████████.php
│   ├── ██████████████.php
│   ├── ████████████████.php
│   ├── ██████████████████████████████.php
│   ├── ███████████████████████.php
│   ├── ███████████████████████████████.php
│   ├── █████████████████████████████.php
│   ├── InvoiceRequest.php
│   ├── ██████████████████████.php
│   ├── ███████████████████.php
│   ├── █████████████████████.php
│   ├── ████████████.php
│   ├── ████████████████████.php
│   ├── ████████████████████████████████████.php
│   ├── ██████████████████████████████████.php
│   ├── ██████████████████.php
│   ├── ███████.php
│   ├── ██████████████████████.php
│   ├── ████████████.php
│   ├── ███████████.php
│   └── ████████████████████████.php
├── Resources
│   ├── ████████████████.php
│   ├── ███████████████.php
│   ├── ██████████████.php
│   ├── ███████████████████████.php
│   ├── █████████████████████████████.php
│   ├── ███████████████████████████.php
│   ├── ███████████████████.php
│   ├── ███████████████.php
│   ├── ████████████████████████████.php
│   ├── ██████████████████████.php
│   ├── ████████████████████████████████████.php
│   ├── ████████████████████.php
│   ├── █████████████████████████████████.php
│   ├── ███████████████.php
│   ├── █████████████████████████████.php
│   ├── ████████████████████.php
│   ├── ████████████████████.php
│   ├── █████████████████████████████████████.php
│   ├── ████████████████████████.php
│   ├── ████████████████.php
│   ├── ████████████████████.php
│   ├── █████████████████████████████████████.php
│   ├── ███████████████████████████████.php
│   ├── ███████████████████████████.php
│   ├── ████████████████████.php
│   ├── █████████████████████.php
│   ├── █████████████████████████.php
│   ├── █████████████████████.php
│   ├── █████████████████.php
│   ├── █████████████████████.php
│   ├── ██████████████████.php
│   ├── █████████████████████████.php
│   ├── █████████████████.php
│   ├── ████████████████.php
│   ├── ████████████████████.php
│   ├── ███████████████████████████████.php
│   ├── ████████████████████████████████.php
│   ├── ████████████████████████████████.php
│   ├── █████████████████████████████.php
│   ├── ███████████████████████████████.php
│   ├── ████████████████████████.php
│   ├── ████████████████████████████.php
│   ├── ████████████████.php
│   ├── █████████████████████.php
│   ├── ███████████████████████.php
│   ├── █████████████████.php
│   ├── Invoices
│   │   ├── InvoiceCollectionDataResource.php
│   │   ├── InvoiceCollectionResource.php
│   │   ├── InvoiceDataResource.php
│   │   ├── InvoiceDraftResource.php
│   │   ├── InvoiceLineDataResource.php
│   │   ├── InvoiceLineResource.php
│   │   ├── InvoiceResource.php
│   │   ├── ██████████████████.php
│   │   ├── █████████████████.php
│   │   └── █████████████.php
│   ├── InvoiceIndexResource.php
│   ├── InvoiceLabelResource.php
│   ├── InvoiceMainOverviewResource.php
│   ├── InvoiceeResource.php
│   ├── ████████████████████.php
│   ├── █████████████.php
│   ├── ███████████████.php
│   ├── ██████████████████████████.php
│   ├── ████████████████████.php
│   ├── ██████████████████.php
│   ├── ██████████████.php
│   ├── █████████████████████████████.php
│   ├── ██████████████████████████.php
│   ├── █████████████████████.php
│   ├── █████████████████████████.php
│   ├── █████████████.php
│   ├── ██████████████████████.php
│   ├── ███████████████████.php
│   ├── ███████████████.php
│   ├── ███████████████.php
│   ├── ███████████████.php
│   ├── █████████████████████.php
│   ├── █████████████.php
│   ├── █████████████████.php
│   ├── ███████████████████.php
│   ├── ███████████████████████.php
│   ├── ██████████████.php
│   ├── ██████████████████████████.php
│   ├── █████████████████.php
│   ├── ██████████████████████.php
│   ├── █████████████.php
│   ├── █████████████████.php
│   ├── ████████████.php
│   ├── ███████████████████████.php
│   ├── ████████████████.php
│   ├── ████████████████████.php
│   ├── ████████████████████████████.php
│   ├── █████████████████████.php
│   ├── ██████████████████████████.php
│   ├── █████████████████.php
│   ├── █████████████████████.php
│   ├── ███████████████████.php
│   ├── ████████████.php
│   ├── ████████████████.php
│   ├── ████████████.php
│   └── █████████████████████.php
└── ViewModels
    ├── █████████████████.php
    ├── ███████████████.php
    ├── ████████████████████████.php
    ├── █████████████████.php
    ├── ████████████████████.php
    ├── █████████████████████████████████.php
    ├── ████████████████████████████.php
    ├── ██████████████████████████.php
    ├── ██████████████████████████████.php
    ├── ████████████████████████.php
    ├── █████████████████.php
    ├── ██████████████████████████████.php
    ├── █████████████████████████.php
    ├── █████████████████████.php
    ├── █████████████.php
    ├── ████████████████.php
    ├── ██████████████████.php
    ├── █████████████████████.php
    ├── ██████████████████████.php
    ├── ██████████████████████████.php
    ├── ██████████████████████.php
    ├── ██████████████████.php
    ├── ████████████████████.php
    ├── ███████████████████.php
    ├── ██████████████████.php
    ├── █████████████████████████████.php
    ├── ██████████████████████████.php
    ├── █████████████████████.php
    ├── █████████████████.php
    ├── ██████████████████████████.php
    ├── ███████████████.php
    ├── ███████████████████████████.php
    ├── ████████████████████████
    │   ├── ████████████████.php
    │   ├── █████████████████.php
    │   ├── ██████████████████.php
    │   └── ███████████████████████.php
    ├── █████████████████████████.php
    ├── ███████████████████████████████.php
    ├── ███████████████████████████████.php
    ├── ███████████████████████.php
    ├── ██████████████████.php
    ├── InvoiceCollectionHabitantContractPreviewViewModel.php
    ├── InvoiceCollectionOwnerContractPreviewViewModel.php
    ├── InvoiceCollectionPreviewViewModel.php
    ├── InvoiceDraftViewModel.php
    ├── InvoiceIndexViewModel.php
    ├── InvoiceLabelsViewModel.php
    ├── InvoiceStatusViewModel.php
    ├── █████████████████.php
    ├── █████████████████████.php
    ├── ██████████████████████.php
    ├── █████████████.php
    ├── ██████████████████.php
    ├── ███████████████████.php
    ├── ██████████████.php
    ├── ██████████████████████.php
    ├── ████████████████████████████.php
    ├── ██████████████████████████████████████.php
    ├── ████████████████.php
    ├── █████████████████.php
    ├── ████████████████████████.php
    ├── ████████████████████████.php
    ├── █████████████████████.php
    ├── ██████████████████.php
    ├── ████████████████████.php
    ├── ██████████████████████████████.php
    ├── █████████████████████████.php
    ├── ███████████████████████████████.php
    ├── ██████████████████.php
    ├── ███████████████.php
    ├── ██████████████.php
    ├── ████████████████████.php
    ├── ████████████████████████.php
    ├── █████████████████.php
    ├── █████████████████████████.php
    ├── ██████████████████.php
    ├── ████████████████████████████.php
    ├── █████████████████████████████.php
    ├── █████████████████████.php
    ├── ██████████████████████.php
    ├── ██████████████████.php
    ├── ██████████████████████.php
    ├── █████████████████████████.php
    ├── ██████████████████████.php
    ├── █████████████████.php
    ├── █████████████.php
    ├── █████████████.php
    ├── ██████████████████████.php
    ├── █████████.php
    └── █████████████████.php

Еще раз привет!

Это было довольно много, чтобы пролистать. Я не шучу. Так выглядел один из наших проектов на самом деле после полутора лет разработки. И имейте в виду, что это только код приложения администратора, он не включает ничего, связанного с доменом.

Так в чем же здесь основная проблема? Это фактически то же самое, что и с нашим доменным кодом в главе 1: мы группируем наш код на основе технических свойств, а не их реального значения; контроллеры с контроллерами, запросы с запросами, модели представления с моделями представления и т. д.

И снова такое понятие, как счета-фактуры, распространяется по нескольким каталогам и смешивается с десятками других классов. Даже при самой лучшей поддержке IDE очень трудно оценить головой все приложение в целом, и нет никакого способа получить общий обзор того, что происходит.

Решение проблемы? Надеюсь, здесь нет никаких сюрпризов; это то же самое, что мы сделали с доменами: сгруппируйте вместе код, который принадлежит друг другу. Вот пример счета-фактуры:

Admin
└── Invoices
    ├── Controllers
    │   ├── IgnoreMissedInvoicesController.php
    │   ├── InvoiceStatusController.php
    │   ├── InvoicesController.php
    │   ├── MissedInvoicesController.php
    │   └── RefreshMissedInvoicesController.php
    ├── Filters
    │   ├── InvoiceMonthFilter.php
    │   ├── InvoiceOfferFilter.php
    │   ├── InvoiceStatusFilter.php
    │   └── InvoiceYearFilter.php
    ├── Middleware
    │   ├── EnsureValidHabitantInvoiceCollectionSettingsMiddleware.php
    │   ├── EnsureValidInvoiceDraftSettingsMiddleware.php
    │   └── EnsureValidOwnerInvoiceCollectionSettingsMiddleware.php
    ├── Queries
    │   ├── InvoiceCollectionIndexQuery.php
    │   └── InvoiceIndexQuery.php
    ├── Requests
    │   └── InvoiceRequest.php
    ├── Resources
    │   ├── InvoiceCollectionDataResource.php
    │   ├── InvoiceCollectionResource.php
    │   ├── InvoiceDataResource.php
    │   ├── InvoiceDraftResource.php
    │   ├── InvoiceIndexResource.php
    │   ├── InvoiceLabelResource.php
    │   ├── InvoiceLineDataResource.php
    │   ├── InvoiceLineResource.php
    │   ├── InvoiceMainOverviewResource.php
    │   ├── InvoiceResource.php
    │   └── InvoiceeResource.php
    └── ViewModels
        ├── InvoiceCollectionHabitantContractPreviewViewModel.php
        ├── InvoiceCollectionOwnerContractPreviewViewModel.php
        ├── InvoiceCollectionPreviewViewModel.php
        ├── InvoiceDraftViewModel.php
        ├── InvoiceIndexViewModel.php
        ├── InvoiceLabelsViewModel.php
        └── InvoiceStatusViewModel.php

Как насчет этого? Когда вы работаете над счетами, у вас есть одно место, чтобы пойти узнать, какой код доступен для вас. Я склонен называть эти группы “модулями приложения” или “модулями” для краткости; и я могу сказать вам по опыту, что они делают жизнь намного проще, когда вы работаете в проектах такого масштаба.

Означает ли это, что модули должны быть сопоставлены один к одному в домене? Определенно нет! Там может быть некоторое пересечение, но это не обязательно. Например: у нас есть модуль настроек в приложении администратора, который касается сразу нескольких групп доменов. Было бы бессмысленно иметь отдельные контроллеры настроек, модели представлений и т. д., распределенные по нескольким модулям: когда мы работаем над настройками, это одна функция сама по себе, а не одна функция, распределенная по нескольким модулям только для того, чтобы быть синхронизированной с доменом.

Другой вопрос, который может возникнуть при рассмотрении этой структуры, – что делать с классами общего назначения. Такие вещи, как базовый класс запросов, middleware, которое используется везде… помните пространство имен Support в первой главе? Вот для чего он нужен! Support содержит весь код, который должен быть глобально доступен, но с таким же успехом он мог бы быть частью фреймворка.

Теперь, когда у вас есть общий обзор того, как мы можем структурировать приложения, пришло время взглянуть на некоторые шаблоны, которые мы используем, чтобы облегчить нашу жизнь. Мы начнем с этого в следующий раз, когда будем говорить о моделях представления.

Оригинал

Рейтинг
( Пока оценок нет )
Maxyc Webber/ автор статьи
Мне 35 лет. Опыт профессиональной разработки 15 лет. Занимаюсь разработкой и поддержкой корпоративных систем автоматизации бизнеса, а также высоконагруженными проектами. Мне нравится решать нестандартные проблемы бизнеса. Имею опыт формирования команд под проект, налаживания процесса разработки, коммуникации программистов и заказчиков. Есть опыт работы с зарубежными заказчиками (ОАЭ, Польша, Германия, Швейцария).
Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.