Как делиться концепциями бизнеса на разных языках программирования?

Мы разрабатываем распределенную систему, созданную из компонентов, реализованных на разных языках программирования (C ++, C # и Python), и обмениваемся друг с другом по сети. Все компоненты системы работают с одними и теми же бизнес-концепциями и обмениваются друг с другом также с точки зрения этих концепций.

В результате мы сильно боремся со следующими двумя проблемами:

  1. Сохранение представления наших бизнес-концепций на этих трех языках в синхронизации
  2. Сериализация / десериализация наших бизнес-концепций на этих языках

Наивным решением для этой проблемы было бы просто трижды определить те же структуры данных (и код сериализации) (для C ++, C # и Python).

К сожалению, это решение имеет серьезные недостатки:

  • Это создает много «дублирования кода»,
  • Для этого требуется огромное количество тестов интеграции на разных языках, чтобы синхронизировать все

Другое решение, которое мы рассмотрели, основано на таких структурах, как ProtoBufs или Thrift. Эти рамки имеют внутренний язык, в котором определены бизнес-концепции, а затем представление этих понятий в C ++, C # и Python (вместе с логикой сериализации) автоматически генерируется этими структурами.

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

Мы чувствуем, что это загрязняет нашу базу кода – любой код в нашей системе, который использует эти автоматически генерируемые классы, теперь «знаком» с этой логикой сериализации / десериализации (серьезная утечка абстракции).

Мы можем обойти это, обернув автоматически сгенерированный код нашими классами / интерфейсами, но это возвращает нас к недостаткам наивного решения.

Может ли кто-нибудь порекомендовать решение, которое обойдет описанные проблемы?

7 Solutions collect form web for “Как делиться концепциями бизнеса на разных языках программирования?”

Лев, вы можете посмотреть на ICE . Он предоставляет объектно-ориентированный IDL с отображением на все языки, которые вы используете (C ++, Python, .NET (все языки .NET, а не только C #, насколько я понимаю)). Хотя ICE – это среда среднего уровня, вам не нужно следовать всем ее политикам.

В частности, в вашей ситуации вы можете определить интерфейсы своих компонентов в ICE IDL и поддерживать их как часть кода. Затем вы можете генерировать код как часть вашей строковой процедуры и работать оттуда. Или вы можете использовать больше возможностей, которые дает вам ICE.

ICE поддерживает структуры данных C ++ STL и поддерживает наследование, поэтому оно должно дать вам достаточно мощный формализм для постепенного создания вашей системы с течением времени с хорошей степенью ремонтопригодности.

Ну, когда-то MS пыталась решить эту проблему с IDL. Ну, на самом деле он пытался решить немного больше, чем определять структуры данных, но, во всяком случае, это все в прошлом, потому что никто в здравом уме не пойдет по COM-маршруту в эти дни.

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

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

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

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

Я согласен с Tristan Reid (обертывание бизнес-логики). На самом деле, несколько месяцев назад я столкнулся с той же проблемой, а затем случайно обнаружил книгу «Искусство программирования Unix» (свободно доступную в Интернете ). Что привлекло мое внимание, было философией отделения политики от механизма (т.е. интерфейсов от двигателей). Современные среды программирования, такие как платформа NET, пытаются интегрировать все под одним доменом. В те дни меня попросили разработать WEB-приложение, которое должно было удовлетворять следующим требованиям:

  1. Он должен быть легко адаптирован к будущим тенденциям пользовательских интерфейсов без необходимости изменения основных алгоритмов.

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

  3. Он должен был работать в Windows и Linux.

Я уверен, что полностью разработал механизм (движки) на C / C ++ и использовал собственные библиотеки ОС (POSIX или WinAPI) и хорошие библиотеки с открытым исходным кодом (postgresql, xml и т. Д.). Я разработал модули двигателей в качестве программ командной строки, и в итоге я реализовал два интерфейса: web (с инфраструктурой PHP + JQuery) и рабочий стол (NET framework). Оба интерфейса не имели ничего общего с механизмами: они просто запускали исполняемые модули основных модулей, вызывая такие функции, как CreateProcess () в Windows или fork () в UNIX, и использовали каналы для мониторинга своих процессов.

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

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

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

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

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

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

Генерация кода может быть правильным выбором здесь, если причиной 2 является ваша проблема. Если существующие генераторы кода не пострадают от ваших потребностей, почему бы вам просто не написать свой собственный? Определите интерфейсы, например, как классы в C #, внесите некоторые мета-атрибуты и используйте отражение в генераторе кода, чтобы извлечь информацию снова при создании соответствующих C ++, Python, а также «реального использования» кода C #. Если вам нужны разные варианты с сериализацией или без нее, сгенерируйте их тоже. Рабочий генератор не должен прилагать больше усилий, чем несколько дней (YMMV в зависимости от ваших требований).

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

Вы можете моделировать эти структуры данных с помощью таких инструментов, как UML-модельер (Enterprise Architect приходит на ум, поскольку он может генерировать код для всех 3.), а затем генерировать код для каждого языка непосредственно из модели.

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

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

  • Объект 'module' не имеет атрибута 'to_bytes' Python
  • Неустранимая ошибка Python при использовании динамической версии Python для выполнения встроенного кода python
  • Встроенная служба обмена сообщениями Chrome не принимает сообщения определенных размеров (Windows)
  • Вызовите код python c c через cython
  • Реализация распознавания лиц с круглой LBP
  • статический класс openCL, который не был правильно выпущен в модуле python, используя boost.python
  • Является ли SSE невыровненной нагрузкой внутренней, чем медленная, чем выровненная нагрузка на процессоры Intel x64_64?
  • swig typemap для python: входные и выходные массивы
  •  
    Interesting Posts for Van-Lav

    Чтение из файла gzip в python

    Создать объект из класса в отдельный файл

    Выровнять по вертикали два графика в matplotlib, если один из них является иллюстративным сюжетом?

    Выполнение нескольких файлов python с использованием одного основного

    Хорошая или плохая практика в Python: импорт в середине файла

    отредактируйте одну строку в нескольких файлах с помощью файловых методов – python

    Есть ли способ вызвать python с xlwings без повторного открытия файла Excel?

    Как вернуть значение из функции, выполняемой QThread и Queue

    Сохранение даты и времени в Django, основанный на часовом поясе объекта

    Отображать массив NumPy как постоянное обновление изображения с помощью Glumpy

    Добавление таблицы пользователей / учетных записей в Postgres в Django View

    json.dumps отменяет порядок

    Google App Engine, как создать собственный файловый объект?

    python pandas из набора элементов в dataframe

    TypeError: данные изображения не могут преобразовываться в float

    Python - лучший язык программирования в мире.