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

10

У меня есть алгоритм с интенсивной логикой, который мне нужен для кодирования на двух языках (на самом деле я закончил его на одном языке удовлетворительно и собираюсь начать кодирование на другом языке). Под интенсивной логикой я подразумеваю, что алгоритм не тривиален, требует тщательного понимания и, что важно, может иметь ошибки (из-за сложности и небрежности, вы знаете), которые должны быть исправлены в будущем.

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

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

К вашему сведению, два языка - это C ++ и Java. C ++ для Windows / Linux и Java для «всего остального», включая Android.

Vin
источник
3
Вы действительно должны повторно реализовать это на другом языке? Почему бы не использовать только Java?
Олекси
@Oleksi Код является лучшим, когда он запускается изначально, поэтому Java был просто компромиссом, когда C ++ не может быть использован.
Vin
13
Просто убедитесь, что вам нужно это представление. Поддержание двух версий программы (особенно одной такой сложной) - колоссальное усилие. Убедитесь, что вам абсолютно необходимо сделать это в C ++, потому что вы заплатите огромные затраты времени и усилий, чтобы сделать это на двух языках.
Олекси
9
Как сказал @Oleksi - если он работает приемлемо в Java на Driod, я не могу себе представить, что, поскольку ПК нужны (возможно, незначительные) улучшения, которые даст C ++. Поскольку вы не заявили, что вы выполняли тесты производительности, я предполагаю, что нет, и в этом случае это воняет преждевременной оптимизации. Пишите на Java, запускайте тесты производительности, оптимизируйте Java. Только тогда рассмотрим переписывание C ++ - сэкономленное время на поддержание одной базы кода, а вместо этого - оптимизацию, почти наверняка закончится поддержанием двух баз кода, двух наборов всего (кроме требований).
Mattnz
@thePrivateProject define работает лучше всего , в любом случае (C ++ или Java) хорошо написанный код должен быть переносимым .

Ответы:

16

Короткий ответ: не делайте этого, если не будете абсолютно вынуждены.

Если вам нужно использовать C ++, то вы можете рассмотреть возможность использования NDK для построения вашего алгоритма для Android на C ++, а затем добавить тонкую оболочку Java для пользовательского интерфейса. Обратите внимание, что использование NDK означает, что ваш код намного менее переносим для различного оборудования. Это определенно не является предпочтительным для использования Java везде, но лучше, чем иметь две базы кода.

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

1) Найдите инструмент, подобный Unity, предназначенный для переносимого программного обеспечения.

2) Попробуйте вставить сложные биты кода в данные или какой-нибудь язык сценариев. Если вы можете написать достаточно общий код для работы с языком сценариев, его проще протестировать и получить право дважды. (Особенно, если это стандартный язык, созданный кем-то другим.) Тогда у вас может быть одна кодовая база для сложных битов. (Вы можете попробовать Lua, который ориентирован на встраиваемость.)

3) Как говорится в другом ответе, создайте набор тестов для проверки обоих кодовых наборов. Обратите внимание, что это действительно трудно понять правильно. Сделав именно это, я могу вам сказать, что это приводит к многочисленным спорам о том, какая версия «правильная», особенно в случаях ошибок.

(2) и (3) могут быть использованы вместе.

Горт Робот
источник
4
Хорошие моменты. Еще одна вещь, о которой стоит подумать - это написать один набор регрессионных тестов и протестировать обе реализации с ним (например, через SWIG).
Джеймс Янгман
15

Создайте один внешний набор тестов, который может обеспечить одинаковое поведение обеих баз кода. Я особо подчеркиваю слово «одиночный», потому что в противном случае вам придется поддерживать два набора тестов, которые могут отличаться в своих утверждениях. У меня нет никаких предложений о том, как это сделать, но кажется, что это один из способов сохранить ваше (и будущие разработчики) здравомыслие при работе с такого рода базой кода.

Джереми Хейлер
источник
4

Вы можете использовать язык, который может компилироваться в машинный код и байтовый код Java, либо сначала преобразовавшись в Java и C ++, либо напрямую. Последнее, что я проверил, у LLVM есть серверы для обоих

редактирование: немного вики-серфинга привело меня к GCJ, который может скомпилировать Java в машинный код

чокнутый урод
источник
4

На мой взгляд, самое важное правило для программиста - «Не повторяй себя». То, что вы предлагаете, является явным нарушением этого правила.

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

  • Используйте язык, специфичный для домена. Возможно, алгоритм может быть лучше выражен на другом языке, например на языке сценариев, для которого может существовать синтаксический анализатор на всех платформах, на которых вы ожидаете запустить приложение, или вы можете генерировать код C ++ / Java на основе кода DSL.

  • Пишите все на C ++. C ++ может быть скомпилирован практически на любую платформу. Если на некоторых платформах требуется, чтобы основное приложение было написано на Java, я бы предположил, что можно вызвать нативную библиотеку (я не очень хорошо разбираюсь в Java, но я предполагаю, что это можно сделать).

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

Пит
источник
Я полагаю, что, по вашему мнению, должна быть одна операционная система, подходящая для офисной работы, один программный пакет для
видеопроигрывателя
1
@mattnz - Вы совершенно не поняли мою точку зрения. Я имею в виду принцип программирования "СУХОЙ". Этот принцип никоим образом не предполагает, что должна быть только одна операционная система, офисный пакет и т. Д. Вы можете легко создать продукт для нескольких платформ, придерживаясь при этом СУХОЙ.
Пит
2

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

Традиционное использование LP состоит в том, чтобы позволить вам чередовать документацию с кодом таким образом, который позволяет вам сохранять документацию очень близко к исходному коду. Один noweb файл (например) может быть использован для создания documenation файла , который может быть скомпилирован в больший документ , используя (скажет) латекс, и производить .cppи .hфайл , который может быть скомпилирован в приложение.

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

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

Марк Бут
источник
2

Это хороший пример того, где могут быть полезны тесты.

Я хотел бы предложить с один набор тестов , которые , как ваш базовый код запуска против. Тогда вы знаете, что ваши кодовые базы соответствуют одной спецификации!

(и иметь хорошее тестовое покрытие!)


источник
1

Рассмотрим код, генерирующий C ++ и Java из другого языка

Ник Кейли
источник
0

отказ

Как упоминалось в предыдущих постах, если у вас нет другого выбора, тогда.

Ответ

Несколько практических предложений, вместо одного ответа:

(1) Используйте общие структуры, даже если одни и те же вещи могут быть выполнены по-разному.

Пример: у меня должен был быть один и тот же код в «Object Pascal» и «C ++», где в обоих случаях есть предложение «if», требуется скобка в «C ++», но не в «Object Pascal».

// Object Pascal
...
if MyBollExpression
begin
  ...
end;
...

// C++
...
if (MyBollExpression)
{
  ...
}
...

Изменился на:

// Object Pascal
...
if (MyBollExpression)
begin
  ...
end;
...

// C++
...
if (MyBollExpression)
{
  ...
}
...

Добавлена ​​скобка для обоих языков. Другим случаем будут необязательные пространства имен по сравнению с требуемыми пространствами имен («пакеты»).

(3) Сохраняйте имена идентификаторов, чувствительность к регистру, особенно типы, подобные, используйте псевдонимы, деление на подклассы, перенос:

// Java
// 
import java.io.*;

...
System.out("Hello World\n");
...

// C++
// 
include <iostream>

...
cout << "Hello World\n";
...

В:

// Java
// 
import java.io.*;

static class ConsoleOut
{
   void Out(string Msg)
   {
     System.out("Hello World\n");
   }
}

...
ConsoleOut MyConsole = new ConsoleOut();
...
MyConsole.out("Hello World\n");
...

// C++
// 
include <iostream>

public class ConsoleOut
{
   void Out(string Msg)
   {
     cout << "Hello World\n";
   }
}

...
ConsoleOut MyConsole = new ConsoleOut();
...
MyConsole.out("Hello World\n");

...

Резюме

Мне обычно приходится работать с несколькими языками программирования, и есть несколько пользовательских «базовых» библиотек, которые я храню на нескольких языках программирования.

Удачи.

umlcat
источник