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


12

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

Ваше приложение взаимодействует с сервером API, написанным на Python .

Сервер Python связывается с базой данных SQL .

У вас также есть веб-сайт для вашего приложения, написанный на JavaScript .

С 4 разными языками легко в конечном итоге повторить по существу одни и те же структуры данных 4 разных раза.

Например, Userтип может выглядеть следующим образом (псевдокод):

type User {
  integer id;
  string name;
  timestamp birthday;
}

Каждая часть проекта будет нуждаться в некотором представлении User. Части Java и Python потребуют двух разных classобъявлений. База данных будет нуждаться в Userобъявлении таблицы. И сайт переднего плана должен будет представлять собой Userтоже.

Повторение этого типа 4 разных раза действительно нарушает принцип «Не повторяй себя» . Также существует проблема, заключающаяся в том, что если Userтип изменяется, то эти изменения необходимо повторять в каждой отдельной части проекта.

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

У кого-нибудь есть какие-либо предложения или ссылки на книги / сообщения в блоге по этому поводу?


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

3
Можно использовать одни и те же структуры данных, если задний и внешний интерфейс используют один и тот же язык. Вы не повторяете себя, если используете разные базы кода. Используйте инструменты для генерации классов из XML-схем или строк Json с разных платформ разработки.
Джон Рейнор

5
Repeating this type 4 different times really breaks the Don't-Repeat-Yourself principle, Это не так. У вас есть 4 разные системы, которые делают разные вещи. Вы слишком далеко зашли СУХОЙ. По моему опыту, тот тип повторного использования, который вы хотите сделать, является семенем зла, потому что вводите тесную связь. Это даже хуже, чем повторить User4 раза на 4 разных языках. В распределенных средах связь является проблемой. СУХОЙ нет.
Laiv

У вас нет времени на ответ: в зависимости от ваших потребностей вы можете попытаться сформулировать правила проверки, используя, например, OWL (поэтому создайте онтологию). Правила проверки становятся «данными», которые можно использовать в необходимых точках. Изменение правил может быть сделано в одном центральном месте.
Даниэль Жур

Ответы:


12

Ты не делай. Или действительно, вы не должны.

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

  • Структуры похожи, но не одинаковы. Даже если 90% структуры одинаковы во всех контекстах. Это 10%, которые принесут вам огромные головные боли.
  • Шаблоны и реализации могут отличаться. Когда используются разные языки и фреймворки, становится слишком сложно иметь одинаковую реализацию во всех них
  • Общие структуры становятся зависимостью, которой необходимо управлять. Наличие общей зависимости значительно усложняет развитие, поскольку великие изменения в одном контексте ужасны в другом. Так много усилий необходимо для координации развития этой общей зависимости
  • Разные контексты имеют разные развертывания. Даже если вам удастся совместно использовать одни и те же структуры данных и один и тот же код проверки во всех контекстах, все же может случиться так, что новая версия одного контекста будет развернута, в то время как другие используют старую версию, поэтому ситуации, когда в версиях все еще существует десинхронизация, все же необходимо быть адресованным

Хотя принцип DRY удивителен, я думаю, что совместное использование структур данных в разных контекстах или слоях создает больше проблем, чем решает. Особенно, если проект становится достаточно большим, чтобы разные люди работали в разных контекстах.


5

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

Найти каноническую форму данных

Чтобы сделать это эффективно, вы должны сначала выяснить, какова каноническая форма данных. Это ваша схема SQL или классы в вашей Java-программе?

Получите (автоматически) другие формы из него

После этого придумайте способ генерировать все другие формы из канонической. Например, предполагая, что вашей канонической формой является схема SQL, вы можете легко сгенерировать код JavaScript, Java и Python из этого (SQL легко разбирается и является хорошим кандидатом для канонического источника).

Приспособьте различия

Должно быть легко пометить разделы сгенерированного кода как «не трогать» - таким образом вы бы учли требуемые различия между всеми различными представлениями (например: пользовательский код, который вы написали для вашего JS-интерфейса и бэкэнда Java), который должны быть сохранены через регенерации.
Возьмите пример с Git; когда он открывает редактор, позволяющий вам ввести сообщение фиксации, файл уже содержит некоторый текст, но у него есть # -------- >8 --------маркер, чтобы знать, где заканчивается ваш контент и где начинается его автоматически сгенерированный текст.

Тем не менее, если вы можете - избегайте такого дублирования. Это PITA, даже если большая часть вашего кода генерируется автоматически.


Этот ответ - немного историческое время, а не «вот несколько лучших практик» - я описал то, что я когда-то делал, когда у меня была та же проблема, что и у вас, и мне нужно было представлять одни и те же данные в разных частях системы (точнее, в двух разных системах).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.