Как следует структурировать приложение Java, где я положил свои классы?

голоса
36

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

Я сам всегда были проблемы с

  • именование,
  • размещение

Так,

  1. Где вы кладете домен конкретных константы (и что это лучшее название для такого класса)?
  2. Где вы положили классы для вещи, которая является как инфраструктурный и домен конкретных (например, у меня есть класс FileStorageStrategy, в котором хранятся файлы, либо в базе данных, или, альтернативно, в базе данных)?
  3. Где поставить исключение?
  4. Существуют ли какие-либо стандарты, к которым я могу сослаться?
Задан 11/08/2008 в 08:45
источник пользователем
На других языках...                            


10 ответов

голоса
22

Я действительно полюбил Maven в типовом каталоге .

Одной из ключевых идей для меня, чтобы иметь два источника корни - один для производства кода и один для тестового кода, как так:

MyProject/src/main/java/com/acme/Widget.java
MyProject/src/test/java/com/acme/WidgetTest.ava

(Здесь, как SRC / основной / Java и SRC / тест / Java являются исходными корнями).

Преимущества:

  • Ваши тесты имеют пакет (или «по умолчанию») уровень доступа к классам при тестировании.
  • Вы можете легко упаковать только ваши источники производства в баночку, понижая SRC / тест / Java в качестве корневого источника.

Одно правило о размещении классов и пакетов:

Вообще говоря, хорошо структурированные проекты будут свободны от круговых зависимостей . Узнайте , когда они плохие (и когда они не ), и рассмотрим такой инструмент , как JDepend или SonarJ , которые помогут вам устранить их.

Ответил 16/08/2008 в 20:06
источник пользователем

голоса
10

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

/src - for your packages & classes
/test - for unit tests
/docs - for documentation, generated and manually edited
/lib - 3rd party libraries
/etc - unrelated stuff
/bin (or /classes) - compiled classes, output of your compile
/dist - for distribution packages, hopefully auto generated by a build system

В / ЦСИ я использую по умолчанию Java СТРУКТУР: имена пакетов , начиная с вашим доменом (org.yourdomain.yourprojectname) и именами классов , отражающих аспекты ООП вы создаете с классом (см других комментаторов). Обычные имена пакетов , как Util , модель , взгляд , события полезны, тоже.

Я склонен ставить константы для конкретной темы в собственном классе, как SessionConstants или ServiceConstants в том же пакете классов домена.

Ответил 12/08/2008 в 09:00
источник пользователем

голоса
7

Где я работаю, мы используем Maven 2 и у нас есть довольно хороший архетип для наших проектов. Цель состояла в том, чтобы получить хорошее разделение задач, таким образом, мы определили структуру проекта с использованием нескольких модулей (по одному для каждого приложения «слоя»): - общий: общий код, используемый другими слоями (например, i18n) - юридических лиц: домен лица - репозитории: этот модуль содержит DAOS интерфейсов и реализации - услуги-Intf: интерфейсы для услуг (например, UserService, ...) - услуги-осущ: реализации услуг (например, UserServiceImpl) - Интернет: все о веб-контента (например, CSS, JSP, JSF страницы, ...) - WS: веб-сервисы

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

Каждый модуль имеет свой собственный базовый пакет, например, если пакет прикладных программ является «com.foo.bar», то мы имеем:

com.foo.bar.common
com.foo.bar.entities
com.foo.bar.repositories
com.foo.bar.services
com.foo.bar.services.impl
...

Каждый модуль уважает стандартную структуру Maven проекта:

   src\
   ..main\java
     ...\resources
   ..test\java
     ...\resources

Юнит-тесты для данного слоя легко найти свое место под \ Src \ теста ... Все, что является проблемно-зависимым имеет это место в модуле сущностей. Теперь что-то вроде FileStorageStrategy должен перейти в модуль хранилищ, так как мы не должны точно знать, что реализация. В слое услуг, мы знаем только интерфейс хранилища, мы не все равно, что конкретная реализация (разделение интересов).

Есть несколько преимуществ такого подхода:

  • четкое разделение проблем
  • каждый модуль packageable в банке (или войны в случае веб-модуля) и, таким образом, позволяет легче повторного использования кода (например, мы могли бы установить модуль в репозитории Maven и использовать его в другом проекте)
  • максимальная независимость каждой части проекта

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

Ответил 15/09/2008 в 21:43
источник пользователем

голоса
3

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

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

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

Ответил 11/08/2008 в 09:00
источник пользователем

голоса
2

Короткий ответ: нарисовать вашу архитектуру системы в терминах модулей, нарисованные бок о бок, с каждым модулем нарезанным вертикально на слои (например , взгляд, модель, настойчивость). Затем используйте структуру как com.mycompany.myapp.somemodule.somelayer , например com.mycompany.myapp.client.view или com.mycompany.myapp.server.model .

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

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

  • com.mycompany.myapp.view
  • com.mycompany.myapp.model
  • com.mycompany.myapp.services
  • com.mycompany.myapp.rules
  • com.mycompany.myapp.persistence (или «дао» для слоя доступа к данным)
  • com.mycompany.myapp.util (остерегайтесь этого используется , как если бы это были «разные»)

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

Ответил 04/09/2008 в 14:40
источник пользователем

голоса
2

Одна вещь, которую я нашел очень полезным для модульных тестов было иметь MYAPP / SRC /, а также MYAPP / test_src / каталоги. Таким образом, я могу поставить модульные тесты в одних и тех же пакетах, как классы они испытывают, и все же я могу легко исключить случаи испытания, когда я готовлю установку производства.

Ответил 03/09/2008 в 13:21
источник пользователем

голоса
2

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

Обычно верхняя часть дерева пакета является доменным именем негативов ( com.domain.subdomain) , чтобы гарантировать уникальность, а затем , как правило , будет пакетом для вашего приложения. Затем подразделяют что смежной области, так что ваш FileStorageStrategyможет идти, скажем, com.domain.subdomain.myapp.storageи тогда могут быть конкретные реализации / подклассы / все , в com.domain.subdomain.myapp.storage.fileи com.domain.subdomain.myapp.storage.database. Эти имена могут быть довольно долго, но importдержит их все в верхней части файлов и Иды может помочь управлять этим , а также.

Исключения , как правило , идут в том же пакете, что и классы , которые бросают их, так что если у вас, скажем, FileStorageExceptionона будет идти в том же пакете FileStorageStrategy. Точно так же интерфейс определения констант будет находиться в том же пакете.

Там на самом деле не какой-либо стандарт как таковой, просто использовать здравый смысл, и если все это становится слишком грязным, реорганизовать!

Ответил 11/08/2008 в 09:24
источник пользователем

голоса
1

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

Ответил 12/08/2008 в 04:36
источник пользователем

голоса
0

Я хотел разорвать мои классы вниз в пакеты, которые связаны друг с другом.

Например: Модель для вызовов базы данных , связанных с

Просмотр классов , которые имеют дело с тем, что вы видите

Контроль классов Основные функциональные возможности

Util Любые разное. классы, которые используются ( как правило , статические функции)

и т.п.

Ответил 12/08/2008 в 02:28
источник пользователем

голоса
0

Одна вещь, которую я сделал в прошлом, - если я простирающийся класс Постараюсь следовать их условности. Например, при работе с Spring Framework, я буду иметь свои классы MVC контроллер в пакете с именем com.mydomain.myapp.web.servlet.mvc Если я не распространяющим то, что я просто идти с тем, что проще. com.mydomain.domain для объектов домена (хотя, если у вас есть тонна домена объектов этот пакет может получить немного громоздким). Для доменов конкретных констант, я на самом деле положить их в качестве общественных констант в наиболее соответствующем классе. Например, если у меня есть класс «член» и есть постоянная максимальная длина имени элемента, я положил его в классе членов. Некоторые магазины делают отдельный класс Константы, но я не вижу значение в комков несвязанных чисел и строк в одном классе. Я видел некоторые другие магазины пытаются решить эту проблему путем создания отдельных констант классов, но это только кажется, что это пустая трата времени, и результат слишком запутанный. С помощью этой установки, большой проект с несколькими разработчиками будут дублировать константы повсюду.

Ответил 12/08/2008 в 00:25
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more