Организация базы исходного кода при смешивании двух или более языков (например, Java и C++)
Вопрос
Несколько дней назад я столкнулся с проблемой, когда мне пришлось добавить файлы C++ в проект Java.Все началось с необходимости измерить загрузку ЦП процессом Java, и было решено, что лучше всего использовать JNI для вызова собственной библиотеки (разделяемой библиотеки на машине Unix), написанной на C.Проблема заключалась в том, чтобы найти подходящее место для размещения файлов C в репозитории исходного кода (кстати, Clearcase), который состоит только из файлов Java.
Я подумал о нескольких альтернативах:
(a) Создайте отдельный каталог для размещения файлов C (в частности, одного файла .h и одного файла .c) в верхней части исходной базы, например:
/vobs/myproduct/javasrc/vobs/myproduct/cppsrc
Мне это не понравилось, потому что у меня всего два файла C и казалось очень странным вот так разбивать исходную базу на уровне языка.Если бы значительная часть проекта была написана более или менее одинаково на C++ и Java, все было бы нормально.
(б) Поместите файлы C в пакет Java, который их использует.
У меня есть вызывающие классы Java в /vobs/myproduct/com/mycompany/myproduct/util/, и туда же помещаются файлы C.
Мне это тоже не понравилось, потому что я думаю, что файлы C просто не принадлежат пакету Java.
Кто-нибудь решал подобную проблему раньше?Какую стратегию лучше всего использовать при организации кодовой базы, сочетающей два или более языков?
Обновлять:Я не планирую использовать в своем проекте какой-либо C или C++, возможно, какой-нибудь Jython, но никогда не знаешь, когда моим клиентам понадобится функция, которую можно решить только с помощью C или лучше всего решить с помощью C.
Решение
«Мне это не понравилось, потому что у меня всего два файла C, и мне показалось очень странным вот так разбивать исходную базу на уровне языка»
Почему это кажется странным?Рассмотрим этот проект:
project1\src\java project1\src\cpp project1\src\python
Или, если вы решите разделить все на модули:
project1\module1\src\java project1\module1\src\cpp project1\module2\src\java project1\module2\src\python
Я думаю, это дело личного вкуса, но приведенная выше структура довольно распространена, и я думаю, что она работает достаточно хорошо, как только вы к ней привыкнете.
Другие советы
Макет по умолчанию, созданный Maven для веб-приложений: src/main/java
, src/test/java
, src/main/resources
, и src/test/resources
.Я предполагаю, что по умолчанию будет добавлено src/main/cpp
и src/test/cpp
также.Мне это кажется достаточно приличным соглашением.
Хорошая идея — хранить их в отдельных папках.Это упрощает поиск файлов C в пакетах Java, а также дает возможность добавлять больше кода C в будущем без необходимости перемещать его позже.
Лично я бы разделил их, возможно, даже на отдельные проекты, но тогда они оба являются отдельными вещами, как будто вы не помещаете две разные концепции в один и тот же класс.Все становится гораздо более расплывчатым, когда они оба касаются одной и той же концептуальной области.Конечно, всегда возникают проблемы, когда дело доходит до построения кода: возможно ли, например, поместить его в структуру b) без необходимости выполнять всевозможные трюки, чтобы заставить его скомпилироваться?Планируете ли вы использовать больше C в проекте? В этом случае файлы C будут распространяться по всему проекту, если вы будете следовать одному и тому же шаблону...
Лично я бы хранил их в отдельных проектах или папках.
Один из способов взглянуть на проблему — относиться к классам C как к любому другому стороннему API.Интерфейс зависимостей (т.е.избегайте прямых вызовов) в вашем Java-коде, чтобы избежать жесткой связи и хранить исходный код C в отдельном проекте/папке от файла java.
Давайте использовать другую терминологию.Есть один продукт, который не является проектом.Продукт состоит из рабочей области Java и рабочей области C/C++, каждая из которых загружается из разных IDE.В конце концов, если вы используете одну и ту же IDE, рабочая область будет только одна.Каждое рабочее пространство состоит из нескольких проектов.Каждый проект имеет свою собственную структуру папок (src, bin, res и т. д.).Поэтому, если это только одно рабочее пространство, лучше иметь внутри хотя бы один проект Java и один проект C/C++, каждый из которых имеет разные компиляции/запуска/отладки/вывода/...настройки.
Итак, я бы использовал:
Product/Workspace(1)/JavaProject1/src
Product/Workspace(1)/JavaProject2/src
Product/Workspace(1 or 2)/CPPproject1/src
Product/Workspace(1 or 2)/CPPproject2/src ...
Таким образом, вы можете в конечном итоге использовать одну и ту же структуру папок для каждого проекта, что является более последовательным.По сути, это всего лишь еще один уровень абстракции — разделение продукта на разные связанные проекты.
В этом случае рассматриваемые файлы не просто представляют собой другой язык, но и запускаются как отдельная программа, взаимодействующая через определенный интерфейс.Это означает, что исходные файлы можно рассматривать как отдельный проект и, следовательно, хранить в другом месте.
Иначе обстоит дело в проектах .NET, которые смешивают C# и ASP.NET (например) в одной базе кода.Как люди организуют свой код в таких случаях?