Почему пакеты и модули являются отдельными понятиями в Java 9?

21

Java 9 будет иметь модули в дополнение к пакетам. Обычно языки имеют один или другой. И большинство программистов воспринимают два термина как синонимы. Модули строятся поверх пакетов, рассматривая их как примитивы. Композитный шаблон предлагает обращаться с примитивами и композитами равномерно. Иначе произойдут плохие вещи. Например, посмотрите на проект Valhalla, где они пытаются модифицировать общий супертип для примитивного (значения) и ссылочного типов.

Являются ли модули и пакеты семантически отдельными понятиями? То есть разумно иметь и то и другое для любого языка (разделение интересов). Или Java должна иметь и то, и другое как дань обратной совместимости?

Зачем вводить новую концепцию, а не дополнять существующую?


JSR 376 : «модульная система платформы Java», реализованная в рамках проекта Jigsaw .

По данным СОТМС

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

JLS тщательно избегает определения того, что представляет собой пакет . Из Википедии :

Пакет Java - это методика организации классов Java в пространства имен, аналогичные модулям Modula, обеспечивающая модульное программирование на Java.

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

Термин пакет иногда используется вместо модуля (как в Dart, Go или Java). В других реализациях это отдельная концепция; в Python пакет представляет собой набор модулей, в то время как в следующей версии Java 9 планируется введение новой концепции модуля (набор пакетов с расширенным контролем доступа).

user2418306
источник
3
Я думаю, что вы задаете много вопросов все вместе здесь? 1) Являются ли модули и пакеты одной семантической идеей? 2) (если не 1), являются ли jigsawмодули -style техническим улучшением по сравнению с пакетами? 3) (если не 1, а если 2), является ли Java просто (или, казалось бы) сохранением обеих концепций для обратной совместимости. Некоторые из этих вопросов отвечают, некоторые в первую очередь ориентированы на мнение. Я думаю, что редактирование, упрощающее разъяснение (я), здесь в порядке.
Терсосаврос
1
@Tersosauros Вы классифицировали «некоторые» вопросы как не по теме, но не указали, какой из них какой. Я вижу это только как один вопрос (1). Другое будет разрешено автоматически. Обратная совместимость для Java это не вопрос. Таким образом, либо java представил модули для исправления недостатков дизайна пакетов, либо два понятия - это действительно отдельные проблемы. И путаница из-за плохого именования.
user2418306
1
Я хочу прояснить вопрос. Но мне нужно понять, какая часть этого вы считаете неопровержимым. Когда я думаю, что есть только одна часть.
user2418306
Ааа, я понимаю путаницу. Я думаю, что вопрос № 1 является ответственным (ответ «да, но нет» - вот где № 3 приходит). Я согласен с # 3, очевидно, что Java не собирается менять то, что такое ключевое слово языка, packageозначает / делает / означает, и при этом они не собираются переходить (давайте посмотрим правде в глаза, довольно ужасно) в систему (ы) classpath в JRE. Вопрос № 2 Я чувствую это , прежде всего , мнение-ориентированный (это не отвечает , но мой ответ , и кто - то другой может отличаться , и ни один из нас обязательно будет неправильно).
Терсосаврос
1
Попробуйте задать четкий вопрос заранее, затем предоставьте вспомогательный материал.
Джей Элстон

Ответы:

22

Понятие модуля отличается от конкретизации этого понятия.

У Java всегда были модули. Метод - это модуль, так же как класс и пакет. Модуль - это единица организации, в которой скрыты внутренние детали и которая взаимодействует с другими модулями по согласованным договорам. Например, метод является модулем, потому что он имеет скрытые внутренние компоненты (код и локальные переменные) и контракт (параметры и тип возвращаемого значения). Модули могут быть составлены из модулей более низкого уровня, например, классы содержат методы.

В ядре Java (до 9) отсутствует развертываемый модуль. Все вышеперечисленные виды модулей не являются развертываемыми блоками, которые можно копировать. В Java есть развертываемый артефакт, называемый файлом JAR, но это не модули, потому что у них нет инкапсуляции или контракта: во время выполнения файлы JAR исчезают, все объединяются в один «путь к классам».

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

Java 9 решает проблему отсутствия развертываемых модулей аналогично OSGi. Возможно, это было совершенно ненужно, потому что OSGi существует и работает, но это совсем другое обсуждение ...

К сожалению, Java 9 мутит воду, называя новую концепцию модуля просто «модулем». Это не означает, что методы, классы и пакеты перестают быть модулями! «Модуль» J9 - это еще одно воплощение концепции модуля . Как и пакеты OSGi, модули J9 состоят из пакетов и представляют собой физические артефакты (как правило, файлы JAR), которые можно копировать. Система времени выполнения понимает и реализует их.

Резюме: да, модули и пакеты J9 являются семантически отдельными понятиями. Очевидно, что для обратной совместимости Java должна сохранить существующую концепцию пакетов. Обратите внимание, что слово «пакет» используется в Java совершенно иначе, чем в других языках или в системах управления пакетами, таких как RPM. Новые модули J9 (и пакеты OSGi) гораздо больше похожи на пакеты в RPM, чем когда-либо были пакеты Java.

Нил Бартлетт
источник
Пакет не соответствует вашему определению модуля. Из-за слабой инкапсуляции и отсутствия средств для объединения других пакетов и уточнения их видимости. Классы могут содержать вложенные классы или поля. Методы могут содержать замыкания или вызывать другие методы. Пакеты не могут "общаться" с другими пакетами.
user2418306
Я не согласен. Пакеты имеют скрытую информацию (типы доступа по умолчанию, методы и поля, также известные как package-private). Пакеты, безусловно, «общаются», потому что код внутри пакета может вызывать код в других пакетах. Это делается против контракта, а именно с публичными типами и методами другого пакета.
Нил Бартлетт
Обратите внимание, что способность агрегировать модульные артефакты на одном уровне (например, методы, содержащие замыкания, классы, содержащие вложенные классы) НЕ является частью моего определения модуля. Если вы считаете это необходимой частью определения модуля, то «модули Java 9» также не являются модулями.
Нил Бартлетт
Я не отрицаю, что в пакетах скрывается информация . Я сказал, что этого недостаточно. importмогу пару пакетов. Но нет способа структурировать пакеты как первоклассные граждане. Эти недостатки (и ограничения OSGi) описаны в JSR 376.
user2418306
Можете ли вы объяснить, почему модули Java 9 также не являются модулями ?
user2418306
10

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

Это одно и то же? Ну да и нет

Из этой статьи JavaWorld о «Модульности в Java 9» :

Пакеты как модульное решение

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

Как намекнул @ user2418306 (OP) , « модули - это правильно выполненные пакеты » . Модули и пакеты в Java (очевидно, в Java 9) семантически одно и то же. То есть они представляют собой наборы предварительно скомпилированных байт-кодов JVM с другими метаданными - по сути , это библиотеки .

Ну какая разница?

Однако разница заключается в метаданных внутри каждого из них. Java- packageманифесты или JAR-манифесты не часто поддерживаются разработчиками библиотек, и при этом они не предоставляют какого-либо точного контракта относительно того, что предоставляет JAR / пакет. Как объяснено здесь (снова статья JavaWorld) :

Разве JAR-файлы недостаточно модульны?

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


Разговор о других языках / средах и т. Д.

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

Управление зависимостями:

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

Теперь поговорим о будущем, как будто я был там

Как упоминалось на этой странице , другие языки (такие как Perl) имеют репозитории пакетов (например, CPAN ). Это возрастающая тенденция (я говорю, потому что я чувствую, что это так, без каких-либо убедительных доказательств), в течение последнего десятилетия или около того. Такие инструменты, как Руби драгоценных камней , Пайтона PyPi , и менеджер пакетов Node ( npm) построить на этом , чтобы обеспечить последовательный способ настройки среды (либо разработки, сборки, тестирования, или во время выполнения, и т.д.) с правом материал (пакеты, модули, драгоценные камни, штуковины и т. д.). Идея (я чувствую) была « заимствована » из дистрибутивных систем Linux®, таких как Debian apt , RedHat'srpmи т. д. (Хотя, очевидно, эволюционировало хотя бы одно поколение, и все эти вещи стали приятнее.)


Java модули , хотя они не обязательно добавить , что вы не можете сделать уже, грим набор инструментов для зависимостей / управления пакетами и автоматизированных сред сборок все гораздо проще. Делает ли это модули «лучше», я отказываюсь говорить. :П

Tersosauros
источник
1
Статье всего 1 год, но она уже устарела. Обсуждается, как управление версиями является фундаментальной характеристикой модуля. Модули Jigsaw не будут иметь информацию о версии. Ничто в сфере управления зависимостями не изменится для конечного пользователя. На самом деле с инструментами сборки все будет намного сложнее. Поскольку они должны поддерживать параллельные реалии classpathи modulepath. И прыгать через обручи, чтобы поддержать юнит-тестирование. Предположение, что два понятия эквивалентны, потому что они представляют совокупность вещей плюс метаданные, слишком смело для меня, чтобы принять. Плюс на полпути вы неожиданно заменили банку на упаковку.
user2418306
Я не сказал « два понятия эквивалентны », я сказал, что они «семантически одно и то же», о чем вы и спрашивали. Кроме того, вы отредактировали вопрос с тех пор, как я ответил, специально упомянув JSR-376 , в отличие от головоломки, о которой говорилось ранее: - /
Tersosauros
Пазл охватывает (реализует) JSR-376. Вопрос по-прежнему связан с обоими, поэтому никакого вреда не было. Словарь определяет эквивалентность как качество или состояние того же значения. И семантически - по смыслу. Извините, но вы педантичны из-за неправильных деталей. Вы сказали, что они эквивалентны. Но вы не предоставили никаких рассуждений. Вместо этого вы ссылаетесь на статью, в которой объясняется, как пакеты и файлы jar не могут быть модулями. Но будущие модули тоже не будут модулями из статьи. Утверждение эквивалентности, а затем обеспечение разницы между 2 (3) противоречиво.
user2418306
Ответить на вопрос нельзя да и нет. Либо два понятия семантически эквивалентны, либо нет. Пожалуйста, не лоботомизируйте мои комментарии и вернитесь к исходному вопросу. Нужны ли языку обе концепции, или это специфическая проблема Java? Если вам нужны разъяснения, я рад помочь.
user2418306