Некоторое время назад я увидел ответ на вопрос, касающийся тонкой организации пакетов Java. Так , например, my.project.util
, my.project.factory
, my.project.service
и т.д.
Я не могу найти его сейчас, поэтому я могу также задать вопрос.
Существуют ли передовые практики в отношении организации пакетов на Java и что с ними происходит?
Как вы организуете свои классы в своем проекте Java?
Например, проект, над которым я работаю с несколькими людьми, имеет пакет, называемый beans. Сначала он был проектом, содержащим простые бины, но в итоге (из-за плохого опыта и нехватки времени) содержал все (почти). Я немного очистил их, поместив некоторые фабричные классы в фабричный пакет (классы со статическими методами, которые создают бины), но у нас есть другие классы, которые выполняют бизнес-логику, и другие, которые выполняют простую обработку (не с бизнес-логикой), например, получение сообщение для кода из файла свойств.
Ваши мысли и комментарии приветствуются.
источник
Ответы:
Организация пакета или структурирование пакета - это обычно горячая дискуссия. Ниже приведены несколько простых рекомендаций по именованию и структурированию пакетов:
com.company.product.modulea
com.company.product.module.web
илиcom.company.product.module.util
т.п.com.company.product.model
иcom.company.product.util
т. д.После нескольких экспериментов и испытаний вы сможете придумать структуру, которая вам удобна. Не зацикливайтесь на одном соглашении, будьте открыты для изменений.
источник
Я организую пакеты по функциям , а не по шаблонам или ролям реализации. Я думаю, что пакеты, как:
beans
factories
collections
не правы.
Я предпочитаю, например:
orders
store
reports
поэтому я могу скрыть детали реализации через видимость пакета . Фабрика заказов должна быть в
orders
упаковке, поэтому детали о том, как создать заказ, скрыты.источник
Краткий ответ: один пакет на модуль / функцию, возможно, с подпакетами. Положите тесно связанные вещи в одном пакете. Избегайте циклических зависимостей между пакетами.
Длинный ответ: я согласен с большей частью этой статьи
источник
Я предпочитаю функцию перед слоями, но я думаю, это зависит от вашего проекта. Рассмотрим свои силы:
Попробуйте минимизировать зависимости пакетов, особенно между функциями. Извлечение API, если это необходимо.
В некоторых организациях команды работают над функциями, а в других - над слоями. Это влияет на организацию кода, использует его для формализации API или поощрения сотрудничества.
Помещение всего в модуль упрощает развертывание и управление версиями, но затрудняет исправление ошибок. Разделение вещей обеспечивает лучший контроль, масштабируемость и доступность.
Хорошо организованный код изменить намного проще, чем большой шарик грязи.
Чем больше, тем более формализованным / стандартизированным он должен быть.
Некоторые коды важнее других. API должны быть более стабильными, чем реализация. Поэтому оно должно быть четко отделено.
Для постороннего лица должна быть возможность узнать, что такое код и с чего начать чтение, посмотрев на дерево пакетов.
Пример:
Это всего лишь пример. Это довольно формально. Например, он определяет 2 интерфейса для feature1 . Обычно это не требуется, но может быть хорошей идеей, если разные люди используют их по-разному. Вы можете позволить внутреннему API расширять общедоступность.
Мне не нравятся имена 'impl' или 'support', но они помогают отделить менее важные вещи от важных (домен и API). Когда дело доходит до именования, мне нравится быть максимально конкретным. Если у вас есть пакет с именем 'utils' с 20 классами, перейдите
StringUtils
к support / string,HttpUtil
support / http и так далее.источник
Не на самом деле нет. Есть много идей и много мнений, но настоящая «лучшая практика» - это использовать ваш здравый смысл!
(Пожалуйста, прочтите « Нет лучших практик», чтобы узнать о «лучших практиках» и людях, которые их продвигают.)
Тем не менее, есть один принцип, который, вероятно, имеет широкое признание. Структура вашего пакета должна отражать (неформальную) структуру модуля вашего приложения, и вы должны стремиться минимизировать (или в идеале полностью избежать) любые циклические зависимости между модулями.
(Циклические зависимости между классами в пакете / модуле просто хороши, но циклы между пакетами, как правило, затрудняют понимание архитектуры вашего приложения и могут стать препятствием для повторного использования кода. В частности, если вы используете Maven, вы обнаружите, что циклический межпакетные / межмодульные зависимости означают, что весь взаимосвязанный беспорядок должен быть одним артефактом Maven.)
Я хотел бы также добавить , что это один широко признаны лучшая практика для имен пакетов. Иными словами, имена ваших пакетов должны начинаться с имени домена вашей организации в обратном порядке. Если вы будете следовать этому правилу, вы уменьшите вероятность проблем, вызванных столкновением ваших (полных) имен классов с другими людьми.
источник
Я видел, как некоторые люди продвигали «пакет за функцией» поверх «пакет за слоем», но за многие годы я использовал довольно много подходов и нашел «пакет за слоем» намного лучше, чем «пакет за функцией».
В дополнение к этому я обнаружил, что гибридная стратегия «пакет за модулем, слой, затем функция» работает очень хорошо на практике, поскольку она имеет много преимуществ «пакет за функцией»:
Я подробно объясняю здесь: структура и структура имени пакета Java но моя стандартная структура пакета:
revdomain.moduleType.moduleName.layer. [layerImpl] .feature.subfeatureN.subfeatureN + 1 ...
Куда:
revdomain обратный домен, например com.mycompany
moduleType [app * | framework | util]
moduleName, например, myAppName, если тип модуля - приложение, или «финансы», если это учетная структура
слой [модель | пользовательский интерфейс | постоянство | безопасность и т. д.,]
layerImpl, напр., wicket, jsp, jpa, jdo, hibernate (Примечание: не используется, если слой является моделью)
характерная черта , например., финансирование
subfeatureN например, бухгалтерский учет
subfeatureN + 1 например, амортизация
* Иногда «приложение» пропускается, если moduleType является приложением, но его размещение делает структуру пакета согласованной для всех типов модулей.
источник
Я не знаю стандартных методов организации пакетов. Я обычно создаю пакеты, которые охватывают довольно широкий спектр, но я могу выделиться в рамках проекта. Например, в личном проекте, над которым я сейчас работаю, есть пакет, посвященный моим настраиваемым элементам управления пользовательским интерфейсом (полный классов, подклассов классов свинга). У меня есть пакет, посвященный моему управлению базой данных, у меня есть пакет для набора слушателей / событий, которые я создал, и так далее.
С другой стороны, я попросил коллегу создать новый пакет почти для всего, что он сделал. Каждый отдельный MVC, который он хотел, получал свой собственный пакет, и казалось, что набор MVC является единственной группой классов, которая может находиться в одном пакете. Я помню, в какой-то момент у него было 5 разных пакетов, в каждом из которых был один класс. Я думаю, что его метод немного экстремален (и команда вынудила его уменьшить количество пакетов, когда мы просто не могли с этим справиться), но для нетривиального приложения, так что все было бы в одном пакете. Это баланс, который вы и ваши товарищи по команде должны найти для себя.
Одна вещь, которую вы можете сделать, это попытаться сделать шаг назад и подумать: если вы были новым участником, представленным в проекте, или ваш проект был выпущен как открытый исходный код или API, насколько легко / сложно было бы найти то, что вы хотите? Потому что для меня это то, чего я действительно хочу из пакетов: организация. Подобно тому, как я храню файлы в папке на моем компьютере, я ожидаю, что смогу найти их снова, не просматривая весь мой диск. Я ожидаю, что смогу найти нужный класс без необходимости поиска в списке всех классов в пакете.
источник