Какую стратегию Вы используете для именования пакета в проектах Java и почему? [закрытый]

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

[114 ]

var arr = [
    [{a: "a"}, {b: "b"}, {c: "c"}, {d: "d"}],
    [{a: "a"}, {b: "b"}],
    [{a: "a"}, {b: "b"}, {c: "c"}],
    [{a: "a"}]
];

let res = arr.reduce((res, curr) =>
{
    curr.forEach((v, i) => res[i] = res[i] ? [...res[i], v] : [v]);
    return res;
}, []);

console.log(res);

Альтернативная версия, в которой могут использоваться только циклы for:

[111 ]

88
задан Sourav Ghosh 17 April 2015 в 08:38
поделиться

13 ответов

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

существуют некоторые дополнительные правила:

  1. слои сложены от самого общего (нижняя часть) к самой определенной (вершине)
  2. , каждый слой имеет открытый интерфейс (абстракция)
  3. , слой может только зависеть от открытого интерфейса другого слоя (инкапсуляция)
  4. , слой может только зависеть от более общих слоев (зависимости сверху донизу)
  5. , слой предпочтительно зависит от слоя непосредственно ниже его

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

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

Для получающегося макета раскладки, это некоторые дополнительные правила:

  • корень каждого имени пакета <prefix.company>.<appname>.<layer>
  • , интерфейс слоя далее разделен функциональностью: <root>.<logic>
  • частная реализация слоя снабжается префиксом частный: <root>.private

Вот расположение в качестве примера.

уровень представления разделен на технологию представления, и дополнительно на (группы) приложения.

com.company.appname.presentation.internal
com.company.appname.presentation.springmvc.product
com.company.appname.presentation.servlet
...

прикладной уровень разделен на варианты использования.

com.company.appname.application.lookupproduct
com.company.appname.application.internal.lookupproduct
com.company.appname.application.editclient
com.company.appname.application.internal.editclient
...

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

com.company.appname.service.clientservice
com.company.appname.service.internal.jmsclientservice
com.company.appname.service.internal.xmlclientservice
com.company.appname.service.productservice
...

уровень интеграции разделен на объекты доступа и 'технологии'.

com.company.appname.integration.jmsgateway
com.company.appname.integration.internal.mqjmsgateway
com.company.appname.integration.productdao
com.company.appname.integration.internal.dbproductdao
com.company.appname.integration.internal.mockproductdao
...

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

, Почему я думаю, вертикальный подход не так хорош?

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

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

33
ответ дан eljenso 24 November 2019 в 07:37
поделиться

Это зависит. В моей строке работы мы иногда разделяем пакеты функциями (доступ к данным, аналитика) или классом активов (кредит, акции, процентные ставки). Просто выберите структуру, которая является самой удобной для Вашей команды.

0
ответ дан quant_dev 24 November 2019 в 07:37
поделиться

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

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

0
ответ дан Bill Michell 24 November 2019 в 07:37
поделиться

Я лично пошел бы для функционального именования. Короткая причина: это избегает дублирования кода или кошмара зависимости.

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

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

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

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

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

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

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

1
ответ дан Varkhan 24 November 2019 в 07:37
поделиться

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

Для меня, это намного легче поддержать и визуализировать в вертикальной системе именования, а не горизонтальный. если component1.display имеет ссылку на component2.dataaccess, который отбрасывает больше звонков предупреждения, чем если бы дисплей component1 имеет ссылку на dataaccess. component2.

, Конечно, компоненты, совместно использованные обоими, входят в свой собственный пакет.

2
ответ дан levand 24 November 2019 в 07:37
поделиться

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

Цели упаковки

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

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

пример моей логической упаковочной структуры

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

Преимущества apple.model apple.store banana.model banana.store

клиент А, использующий Banana.store. BananaStore только подвергнут функциональности, которую мы хотим сделать доступным. Быть в спящем режиме версия является деталью реализации, которая они не должны знать, и при этом они не должны видеть эти классы, поскольку они добавляют помеху к операциям обращения к ЗУ.

Другие Логические v Функциональные преимущества

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

, Почему функциональность?

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

Разработчик изменяется на систему

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

3
ответ дан mP. 24 November 2019 в 07:37
поделиться

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

Это кажется, что Ваша логическая, вертикальная система могла бы иметь тенденцию "порочить" зависимости через большинство пакетов. Таким образом, если каждая функция будет упакована как вертикальная часть, то каждый пакет будет зависеть от каждой сторонней библиотеки, которой Вы пользуетесь. Любое изменение в библиотеке, вероятно, будет слегка колебаться через Вашу целую систему.

3
ответ дан erickson 24 November 2019 в 07:37
поделиться

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

Обычно части являются достаточно значительными, что они разбиты в отдельные артефакты сборки, куда Вы могли бы поместить базовую функциональность в одну банку, пчелу в другого, сеть frontend материал в warfile, и т.д.

4
ответ дан Ben Hardy 24 November 2019 в 07:37
поделиться

Существуют обычно оба уровни существующего подразделения. От вершины существуют единицы развертывания. Их называют 'логически' (в Ваших терминах, думайте функции Eclipse). В единице развертывания у Вас есть функциональное подразделение пакетов (думайте плагины Eclipse).

, Например, функция com.feature, и она состоит из com.feature.client, com.feature.core и com.feature.ui плагины. В плагинах у меня есть очень мало подразделения к другим пакетам, хотя это весьма обычно также.

Обновление: Btw, существует большой разговор Juergen Hoeller об организации кода в InfoQ: http://www.infoq.com/presentations/code-organization-large-projects . Juergen является одним из архитекторов Spring и знает много об этом материале.

5
ответ дан Peter Štibraný 24 November 2019 в 07:37
поделиться

Я придерживаюсь с Дядей Bob принципы дизайна упаковки . Короче говоря, классы, которые должны быть снова использованы вместе и изменены вместе (по той же причине, например, изменению зависимости или изменению платформы) должны быть помещены в тот же пакет. IMO, функциональная разбивка имела бы лучший шанс достижения этих целей, чем vertical/business-specific разбивка в большинстве приложений.

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

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

18
ответ дан Buu Nguyen 24 November 2019 в 07:37
поделиться

Это зависит от гранулярности Ваших логических процессов?

, Если они автономны, у Вас часто есть новый проект для них в управлении исходным кодом, а не новом пакете.

проект, я иду в данный момент, допускает ошибку к логическому разделению, существует пакет для jython аспекта, пакет для механизма правила, пакеты для нечто, панели, binglewozzle, и т.д. Я смотрю на наличие определенных синтаксических анализаторов/устройств записи XML для каждого модуля в том пакете, вместо того, чтобы иметь XML-пакет (который я сделал ранее), хотя все еще будет базовый XML-пакет, куда общая логика идет. Одна причина этого однако состоит в том, что это может быть расширяемо (плагины), и таким образом каждый плагин должен будет также определить свой XML (или база данных, и т.д.) код, так централизация, это могло представить проблемы позже.

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

то, Что необходимо, является отмеченными пространствами имен. Синтаксический анализатор XML для некоторой функциональности Jython мог быть отмечен и Jython и XML, вместо того, чтобы иметь необходимость выбрать один или другой.

Или возможно я - wibbling.

2
ответ дан JeeBee 24 November 2019 в 07:37
поделиться

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

Возьмем, к примеру, плагин Eclipse: размещение всех представлений или действий в одном пакете было бы беспорядком. Вместо этого каждый компонент функции должен перейти в пакет функции или, если их много, в подпакеты (featureA.handlers, featureA.preferences и т. Д.)

Конечно, проблема заключается в иерархической системе пакетов (которая среди другие есть в Java), что делает обработку ортогональных проблем невозможной или, по крайней мере, очень сложной - хотя они встречаются повсюду!

2
ответ дан 24 November 2019 в 07:37
поделиться

Это интересный эксперимент - вообще не использовать пакеты (кроме корневого пакета).

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

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

1
ответ дан 24 November 2019 в 07:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: