Как должна быть зависимость между проектами?

Насколько проекты должны быть независимы друг от друга?

У меня есть очень большое решение Visual Studio, в котором все проекты зависят друг от друга. Я не могу взять один проект из решения и добавить его в другое решение на другом компьютере, потому что все они связаны друг с другом.

Я правильно все делаю?


Например;

Рассмотрим эти три моих проекта (пары «Дисковый файл», «Конвертер данных» и «Math — .h» и «.cpp» — это классы C ++; я упомяну их под соответствующим именем):

The Solution
|
|---- Disk File
|     |
|     |---- BinaryFile.h, BinaryFile.cpp
|     |---- TextFile.h, TextFile.cpp
|
|---- Data Converter
|     |
|     |---- Utf8.h, Utf8.cpp
|     |---- XmlParser.h, XmlParser.cpp
|     |---- StringFormatter.h, StringFormatter.cpp
|
|---- Math
|
|---- Plotter2D.h, Plotter2D.cpp
|---- Matrix.h, Matrix.cpp
  • TextFile использования Utf8 для кодировки символов. Что делает Disk File зависит от Data Converter,
  • XmlParser использования TextFile, Что делает Data Converter зависит от Disk File,
  • Plotter2D использования TextFile для сброса некоторых данных для использования с внешним программным обеспечением, и Matrix использует некоторые инструменты форматирования строки в его ::ToString() метод. Что делает Math зависит от обоих Disk File а также Data Converter,

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

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

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

Мне нужны ваши предложения.

1

Решение

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

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

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

  3. Также вы можете использовать функции «extern C».

0

Другие решения

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

Кроме того, вы должны постараться максимально разорвать зависимости. Например, делает XmlParser очень нужно TextFile? Или может приложение, которое хочет проанализировать текстовый файл, создать последний, прочитать содержимое в строку и передать его XmlParser? Если вам удастся до второго, то XmlParser больше не зависит от TextFile,

Еще одна вещь, чтобы рассмотреть это тип зависимости, которую вы создаете. Используя тот же пример, TextFile используется в общедоступном интерфейсе XmlParser? Это нужно использовать там? Если XmlParser зависит от TextFile вам нужно будет связать библиотеку, если она является частью интерфейса, то пользователи XmlParser придется включать заголовки TextFile создавая высшую связь. В этом случае вы можете, например, передать имя файла XmlParser вместо TextFile удалить зависимость от интерфейса.

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

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

0

Лучшим подходом было избежать цикла зависимости между проектами, в вашем случае классы утилит, такие как «Дисковый файл» и «Конвертер данных», могли существовать в одном проекте, и вы можете использовать пространства имен для обеспечения модульности.

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

0
По вопросам рекламы [email protected]