Quels sont les moyens de conserver des bases de code écrites dans deux langues qui implémentent la même logique?

10

J'ai un algorithme intensif logique que je dois coder en deux langues (en fait, je l'ai terminé dans une langue de manière satisfaisante et je suis sur le point de commencer à coder dans l'autre langue). Par logique, je veux dire que l'algorithme n'est pas trivial, a besoin d'une compréhension approfondie et, surtout, pourrait avoir des bugs (en raison de la complexité et de la négligence, vous savez) qui devraient être corrigés à l'avenir.

De plus, je veux m'assurer que lorsque ce code change de mains, il ne doit finalement pas submerger les nouveaux programmeurs.

Dans ce scénario, quels sont les moyens qui permettraient de maintenir les bases de code et de les synchroniser? Par moyens, j'entends les outils logiciels, les meilleures pratiques, etc.

Pour info les deux langages sont C ++ et Java. C ++ pour Windows / Linux et Java pour "tout le reste", y compris Android.

vin
la source
3
Devez-vous vraiment le réimplémenter dans une autre langue? Pourquoi ne pas utiliser uniquement Java?
Oleksi
@Oleksi Le code est meilleur lorsqu'il s'exécute en mode natif, donc Java n'était qu'un compromis où C ++ ne peut pas être utilisé.
vin
13
Assurez-vous simplement que vous avez besoin de cette performance. La maintenance de deux versions d'un programme (en particulier une de ce complexe), est un effort colossal. Assurez-vous que vous devez absolument le faire en C ++, car vous allez payer un coût énorme en temps et en efforts pour le faire en deux langues.
Oleksi
9
Comme l'a dit @Oleksi - s'il fonctionne de manière acceptable en Java sur un Driod, je ne peux pas imaginer que le PC a besoin des améliorations (probablement marginales) que C ++ apportera. Comme vous n'avez pas déclaré que vous avez exécuté des tests de performances, je suppose que non, auquel cas cela pue l'optimisation prématurée. Écrivez en Java, exécutez des tests de performances, optimisez Java. N'envisagez alors qu'une réécriture C ++ - le temps gagné à maintenir une base de code, mis à l'optimisation à la place, assurera presque certainement la maintenance de deux bases de code, deux ensembles de tout (sauf les exigences).
mattnz
@thePrivateProject define fonctionne mieux , dans les deux cas (C ++ ou Java) un code bien écrit doit être portable .

Réponses:

16

Réponse courte: ne faites cela que si vous y êtes absolument contraint.

Si vous devez utiliser C ++, vous pouvez envisager d'utiliser le NDK pour créer votre algorithme pour Android en C ++, puis ajouter un wrapper Java fin pour l'interface utilisateur. Notez que l'utilisation du NDK signifie que votre code est beaucoup moins portable sur différents types de matériel. Ce n'est certainement pas préférable à l'utilisation de Java partout, mais mieux que d'avoir deux bases de code.

Si vous ne pouvez absolument pas le faire et devez avoir deux bases de code, voici trois suggestions:

1) Recherchez un outil comme Unity conçu pour les logiciels portables.

2) Essayez d'extraire les bits complexes du code en données ou en langage de script. Si vous pouvez écrire du code assez générique pour gérer le langage de script, il est plus facile de tester et de réussir deux fois. (Surtout s'il s'agit d'un langage standard créé par quelqu'un d'autre.) Vous pouvez alors avoir une base de code pour les bits complexes. (Vous pouvez essayer Lua, qui est orienté vers l'intégration.)

3) Comme l'indique l'autre réponse, créez une suite de tests pour valider les deux jeux de codes. Notez que c'est vraiment difficile à faire correctement. Après avoir fait exactement cela, je peux vous dire que cela fait l'objet de nombreux débats sur la version qui est "correcte", en particulier dans les cas d'erreur.

(2) et (3) peuvent être utilisés ensemble.

Gort le robot
la source
4
Bons points. Une autre chose à penser est d'écrire un ensemble de tests de régression et de tester les deux implémentations avec lui (par exemple via SWIG).
James Youngman
15

Créez une seule suite de tests externes qui peut garantir que les deux bases de code se comportent de la même manière. J'ai mis un accent supplémentaire sur le mot "single" car sinon vous devrez maintenir deux suites de tests qui peuvent différer dans leurs affirmations. Je n'ai aucune suggestion sur la façon de procéder, mais cela semble être un moyen de maintenir votre santé mentale (et celle des futurs développeurs) lorsque vous travaillez sur ce type de base de code.

Jeremy Heiler
la source
4

vous pouvez utiliser un langage qui peut être compilé en code machine et en octet java soit en le transformant d'abord en java et C ++, soit directement. La dernière fois que j'ai vérifié que LLVM a des backends pour les deux

edit: un peu de navigation sur wiki m'a amené à GCJ qui peut compiler java en code machine

monstre à cliquet
la source
4

À mon avis, la règle la plus importante pour un programmeur est "Ne vous répétez pas". Ce que vous suggérez est une violation claire de cette règle.

Je vous suggère sérieusement de trouver un moyen de n'implémenter l'algorithme qu'une seule fois. Je peux actuellement penser à deux approches différentes.

  • Utilisez une langue spécifique au domaine. Peut-être que l'algorithme peut être mieux exprimé dans un langage différent, par exemple un langage de script, pour lequel un analyseur peut exister sur toutes les plateformes sur lesquelles vous prévoyez d'exécuter l'application, ou vous pouvez générer du code C ++ / Java basé sur le code DSL.

  • Écrivez tout en C ++. C ++ peut être compilé sur pratiquement n'importe quelle plate-forme. Si sur certaines plates-formes vous avez besoin que l'application principale soit écrite en Java, je suppose qu'il est possible d'appeler une bibliothèque native (je ne suis pas très compétent en Java, mais je suppose que cela peut être fait).

Le maintien du même algorithme sur deux plates-formes différentes ne peut entraîner que des problèmes et des bugs.

Pete
la source
Je suppose qu'à votre avis, il devrait y avoir un système d'exploitation, sur la combinaison de productivité de bureau, un logiciel de lecteur vidéo ........
mattnz
1
@mattnz - Vous avez tout à fait mal compris mon point. Je fais référence au principe de programmation de "DRY". Ce principe ne suggère nullement qu'il ne devrait y avoir qu'un seul système d'exploitation, suite bureautique, etc. Vous pouvez facilement produire un produit pour plusieurs plates-formes tout en respectant DRY.
Pete
2

En plus des excellents conseils pour utiliser une suite de tests externe commune, vous voudrez peut-être vous pencher sur la programmation alphabétisée . Les outils de programmation alphabétisés vous permettent de produire plusieurs fichiers à partir d'un seul fichier source.

L'utilisation traditionnelle de LP est de vous permettre d'entrelacer la documentation avec le code d'une manière qui vous permet de garder la documentation très proche du code source. Un seul fichier noweb (par exemple) pourrait être utilisé pour générer un fichier de documentation qui pourrait être compilé dans un document plus grand en utilisant (disons) LaTex, et produire un fichier .cppet .hqui pourrait être compilé dans votre application.

Dans votre cas, cela pourrait vous permettre de conserver les bases de code et la documentation ensemble, en produisant également un .javafichier.

Garder la documentation et les différentes versions de code ainsi que dans un seul fichier, divisé en sections logiquement équivalentes, devrait le rendre beaucoup plus facile de les garder tous synchronisés les uns avec les autres.

Mark Booth
la source
2

Ceci est un bon exemple de cas où les tests peuvent être utiles.

Je suggère d' avoir une suite de test unique à la fois votre base de code exécuté sur. Vous savez alors que vos bases de code sont toutes deux conformes à la même spécification!

(et, ayez une bonne couverture de test!)


la source
1

Envisagez de générer du code C ++ et Java à partir d'un autre langage

Nick Keighley
la source
0

Avertissement

Comme mentionné dans les articles précédents, si vous n'avez pas vraiment d'autre choix, alors.

Réponse

Plusieurs suggestions pratiques, au lieu d'une seule réponse:

(1) Utilisez des structures communes, même si les mêmes choses peuvent être faites différemment.

Exemple: je devais avoir le même code dans "Object Pascal" et "C ++", où la phrase "if" existe dans les deux, la parenthèse dans "C ++" est requise, mais pas dans "object Pascal".

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

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

Changé en:

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

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

Ajout de parenthèses dans les deux langues. Un autre cas sera les espaces de noms facultatifs par rapport aux espaces de noms requis ("packages").

(3) Conserver les noms des identificateurs, la sensibilité à la casse, spécialement les types, similaires, utiliser des alias, sous-classer, encapsuler:

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

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

// C++
// 
include <iostream>

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

Dans:

// 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");

...

Sommaire

Je dois généralement travailler avec plusieurs langages de programmation, et il existe des bibliothèques "de base" personnalisées que je garde dans plusieurs langages de programmation.

Bonne chance.

umlcat
la source