Плюсы и минусы организации пакетов в проекте Java

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

Поэтому я хочу знать подходы других людей к работе с пакетами. Вы предпочитаете иметь много пакетов с небольшим количеством классов или несколько пакетов с большим количеством классов? Вы предпочитаете отделять реализации от интерфейсов? И так далее ... В целом ваши повседневные привычки использования пакетов и плюсы / минусы вашего подхода.

Спасибо за ваши сообщения.


person michal.kreuzman    schedule 03.03.2011    source источник


Ответы (2)


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

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

Насколько мне известно, существуют две основные школы организации классов в пакеты:

  1. Сначала разбивка по модулям. Здесь ваши пакеты более высокого уровня - это разные модули системы, и вы можете разделить их по функциям.
  2. Организация по функциям. Здесь вы сначала упорядочиваете по функциям (например, все классы контроллеров в одном пакете, все ваши контейнеры данных в другом и т. Д.) И, при необходимости, разделяете их по модулям.

У обеих систем есть свои плюсы и минусы, я считаю их примерно одинаковыми, хотя я немного предпочитаю модульный подход.

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

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

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

Но если у вас есть несколько реализаций для данного интерфейса, то да, я бы разделил их. Например, интерфейс будет com.foo.Bar, а реализации будут выглядеть как com.foo.bars.CrowBar, com.foo.bars.TaskBar. Очевидно, что если ваши реализации принадлежат разным модулям, вы должны изменить его на com.foo.moduleX.bars.CrowBar или com.foo.bars.moduleX.CrowBar, в зависимости от того, какой системе вы следуете.

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

person biziclop    schedule 03.03.2011
comment
Спасибо за исчерпывающий ответ. У меня на уме вопрос. А что насчет подмодулей в модулях, вы тоже создаете для них пакеты? Например ,com.foo.moduleX.submoduleX., com.foo.moduleX.submoduleY. - person michal.kreuzman; 04.03.2011

Я предпочитаю ограничивать объем моих классов и методов частными или защищенными пакетами, где это возможно (чтобы они не загромождали автозаполнение Eclipse :), что автоматически означает, что пакеты могут содержать довольно много классов.

Я предпочитаю отделять объекты бизнес-данных (DAO) от их репозиториев / служб поиска, которые отделены от объектов и представлений бизнес-логики.

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

Важно одно: публично экспортируемый интерфейс (общедоступные интерфейсы, перечисления и классы) должен быть в некоторой степени связан, чтобы документация по пакету показывала некоторую сплоченность.

person extraneon    schedule 03.03.2011