Які існують способи підтримки кодових баз, написаних двома мовами, що реалізують ту саму логіку?


10

У мене є логічно інтенсивний алгоритм, який мені потрібно кодувати двома мовами (фактично я закінчив його однією мовою задовільно і збираюся розпочати кодування на іншій мові). За логікою, я маю на увазі, що алгоритм нетривіальний, потребує ретельного розуміння, і, що важливо, може виникнути помилки (через складність та необережність, ви знаєте), які повинні бути виправлені в майбутньому.

Крім того, я хочу переконатися, що коли цей код змінить руки, з часом він не повинен переповнювати нових програмістів.

Враховуючи цей сценарій, які способи допоможуть підтримувати бази даних та підтримувати їх синхронізацію? Я маю на увазі програмні засоби, передовий досвід тощо.

FYI двома мовами є C ++ і Java. C ++ для Windows / Linux та Java для "всього іншого", включаючи Android.


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, але припускаю, що це можна зробити).

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


Я думаю, на вашу думку, має бути одна операційна система, на костюмі продуктивності офісу, один програмний пакет відеопрогравача ........
mattnz

1
@mattnz - Ви абсолютно не зрозуміли мою думку. Я маю на увазі принцип програмування "DRY". Цей принцип ні в якому разі не говорить про те, що повинна бути лише одна операційна система, офісний пакет тощо. Ви можете легко виготовити продукт на декількох платформах, дотримуючись DRY.
Піт

2

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

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

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

Зберігання документації та різних версій коду в одному файлі, розділеному на логічно еквівалентні розділи, повинно значно полегшити їх синхронізацію між собою.


2

Це хороший приклад, коли тести можуть бути корисними.

Я б запропонував створити єдиний тестовий набір, проти якого обидва ваші кодові бази. Тоді ви знаєте, що обидві бази коду відповідають одній і тій же специфікації!

(і, мати хороше тестове покриття!)



0

Відмова від відповідальності

Як згадувалося в попередніх публікаціях, якщо у вас дійсно немає іншого вибору, тоді.

Відповідь

Замість однієї відповіді кілька практичних пропозицій:

(1) Використовуйте загальні структури, навіть якщо однакові речі можна зробити різними.

Приклад: мені довелося мати той самий код у "Object Pascal" & "C ++", де пропозиція "якщо" існує в обох, потрібні дужки в "C ++", але не в "об'єкті 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");

...

Підсумок

Мені зазвичай доводиться працювати з декількома мовами програмування, і є деякі власні "основні" бібліотеки, які я зберігаю в декількох мовах програмування.

Щасти.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.