Должен ли я организовать свои папки по бизнес-доменам или техническим доменам?

19

Например, если я использую какую-то MVC-подобную архитектуру, какую структуру папок мне следует использовать:

domain1/
    controller
    model
    view
domain2/
    controller
    model
    view

Или:

controllers/
    domain1
    domain2
models/
    domain1
    domain2
views/
    domain1
    domain2

Я намеренно пропустил расширения файлов, чтобы этот вопрос не зависел от языка.

Лично я предпочел бы разделить по бизнес-доменам (интуитивное чувство), но я вижу, что большинство / много фреймворков разделены по техническим областям. Почему я должен выбрать один над другим?

Флориан Маргейн
источник
2
фреймворки ориентированы на разработчиков, а не на бизнес-пользователей. Ожидается, что разработчикам будет удобнее использовать технически ориентированный подход, и фреймворки учтут это - это может быть причиной того, что вы наблюдаете
коммент

Ответы:

15

Я думаю, что это зависит от конкретного проекта.

Например, если разные бизнес-домены полностью независимы друг от друга, я бы организовал их по бизнес-доменам.

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

Существует также (золотая) середина между ними - раздели общий код в его собственный домен и используй его в других доменах. Это дает вам интуитивно понятное расположение, но позволяет использовать общий код для бизнес-доменов.

Domain1              # This domain changes bits of standard MVC code
  controllers
  models
  views
Domain2              # this domain only modifies views, all else is standard
  views
Shared               # Here is the better part of code base
  controllers
  models
  views

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

РЕДАКТИРОВАТЬ:

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

Конечно, вы можете раскошелиться на проект для каждой из этих компаний. Но если структура / язык позволяет, вы можете использовать подклассы или плагины и т. Д., Чтобы настроить отдельные части общего проекта в соответствии с потребностями каждого клиента и организовать их в макетах Business Domain.

Например, если общий проект экспортирует в JSON только сам элемент, Domain1 может создать подкласс контроллера и заставить его экспортировать также недавние проблемы с доставкой.

И если позже вы обнаружите, что Domain1 имеет компонент, который также подходит для Domain2, вы можете извлечь его общую версию в Shared.

Как вы сказали, многие фреймворки организованы по техническим областям, и это то, что я использовал на данный момент, просто потому, что мой выбор FW делает это проще. Но с небольшим (или большим) количеством консистентной смазки, я думаю, я мог бы также переписать пути включения для поддержки макета Business Domain.

Laas
источник
Я думаю, что идея замечательная, но я не могу представить практический пример. Не могли бы вы дать простой, но поучительный?
Florian Margaine
@FlorianMargaine - я приведу пример из реальной жизни. Сайты недвижимости. На моей последней работе мы продали несколько сайтов по недвижимости многим клиентам. У нас была централизованная база данных для всех 50+ клиентов. Каждый внутренний администратор использовал общий набор модулей. Каждый клиент, обращенный к стороне, использовал уникальные изображения и навигацию. При каждом поиске и развертывании страниц использовались общие модули, кроме случаев, когда клиенту требовались одноразовые функции. Для этих разовых мы разделили код и дали им свой собственный модуль. (Недостаток: Обновления должны были быть сделаны в общих модулях и дублированы в одноразовых модулях)
Майкл Райли - AKA Gunny
8

Я думаю, что очень интересно спросить: «Что я могу добавить на регулярной основе, больше доменов или больше технических разделов?» Тогда, каков бы ни был ответ, поместите это на верхний уровень.

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

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

Держите вещи вместе, если они могут измениться одновременно.

Скотт Уитлок
источник
Лучший совет, но я не знаю, как предсказать, какие домены я собираюсь добавить больше всего.
Florian Margaine
Последнее предложение прибивает это.
Hakan Deryal
@FlorianMargaine - я не думаю, что «вид» домена имеет значение. Если вы добавляете домены больше, чем добавляете новые технические «вещи», то сначала группируйте все по доменам.
Скотт Уитлок
3

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

Ваше основное приложение будет просто использовать их и ссылаться на них.

В основном ваш вопрос также о сплоченности и сцеплении. Вы хотите, чтобы отдельные части работали максимально независимо. Таким образом, вы получаете тестируемый и повторно используемый код.

Принимая это во внимание: если бы вы разделились по доменам, как бы вы повторно использовали части своего приложения? Например, возьмем интернет-магазин: поступает запрос для / orders / view / 1, поэтому вам нужно показать номер заказа. 1. Переходит к / orders / controllers / order_controller. Если вы разделили домен по продуктам и заказам, вам уже потребуются части другого «домена».

Там вы можете начать взаимодействовать, но, скорее всего, в большинстве случаев они слишком сплоченные. Если вы принимаете технический подход. Например, у вас может быть плагин для обработки заказов. Вы помещаете в него объекты Product из своего центрального приложения. Таким образом, вы можете легко протестировать плагин, просто создайте объект Product с именем и ценой и отправьте его.

Плагин будет делать именно то, что ему нужно. Это будет зависеть от его ввода, а не от других «частей / доменов / областей».

Люк Франкен
источник
Хорошая идея. По сути, это мой ответ сверху вниз. Я поместил общий код на вершине и в основном подключил специфику домена. Вы помещаете Домен вверху и подключаете Общий код. Я думаю, что оба являются одинаково хорошими подходами относительно разъединения и тестируемости.
Laas
2

Microsoft ASP.Net MVC 3 имеет понятие «Области». Когда вы вводите «Области» в свой проект MVC, они разбивают его следующим образом:

area1/
   models
   views
   controllers
area2/
   models
   views
   controllers

Я нашел это вполне естественным. Область - это «большой кусок» проекта, и работа в автономном блоке просто имеет большой смысл.

Мы использовали пространства имен, чтобы соответствовать, FWIW.

gahooa
источник
2
Спасибо за ваш вклад, но как это ответит на мой вопрос? (Сравнение обоих решений)
Флориан Маргейн
@FlorianMargaine: я иллюстрирую, как Microsoft сделала это, с (возможно, ошибочным) предположением, что они приложили немало усилий для выбора более разумного пути. Надеюсь, что это дает некоторый вклад.
gahooa
Хорошо, но это бизнес-ориентированный способ, который я показал в своем вопросе ...
Florian Margaine
1

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

Некоторые детали для тех, кто заинтересован: Когда проект был запущен 5 лет назад, разработчики создали следующую структуру пакета:

com
  example
    web
      struts
        action
        form
      shared
      functionality1
      functionality2

Каждая функция магазина, такая как корзина покупок, поиск товара и т. Д., Состоит из нескольких действий, каждое из которых имеет свой собственный класс формы (структура, предписанная платформой MVC). В результате мы получили более 200 классов в пакете действий, каждый из которых полностью отделен от связанного с ними класса формы. Что еще хуже, действия не реализуют слишком много логики, а вызывают специфичные для функции сервисы, которые находятся в еще одном пакете.

Я предложил и убедил команду, что мы должны перейти к организации пакетов по бизнес-доменам. Аргументация проста: если вы действительно хотите увидеть список всех действий, вы можете просто открыть представление иерархии типов любой достойной IDE. Однако то, что IDE не может сделать, это вывести бизнес-домен, к которому принадлежит класс. Кроме того, этот подход позволяет вам делать общедоступными только те классы, которые необходимы для некоторых функций, оставляя остальное на видимости пакета.

Йенс Баннманн
источник
0

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

Лично я думаю, что гораздо проще хранить мой Foo Controller и Foo Repository или что-либо еще вместе, чем переходить назад и вперед между папкой Controller и папкой Repository, так как мне часто приходится работать над обоими при добавлении функций вокруг Foo. В более крупных проектах это еще более важно, поскольку расстояние между техническими папками может быть значительным и стать заметной тратой времени при разработке.

Квентин-starin
источник