Wie können Codebasen in zwei Sprachen verwaltet werden, die dieselbe Logik implementieren?


10

Ich habe einen logikintensiven Algorithmus, den ich in zwei Sprachen codieren muss (tatsächlich habe ich ihn in einer Sprache zufriedenstellend beendet und bin dabei, mit dem Codieren in der anderen Sprache zu beginnen). Mit logikintensiv meine ich, dass der Algorithmus nicht trivial ist, sorgfältiges Verständnis erfordert und vor allem Fehler aufweisen könnte (aufgrund von Komplexität und Nachlässigkeit, wissen Sie), die in Zukunft behoben werden müssten.

Außerdem möchte ich sicherstellen, dass dieser Code, wenn er den Besitzer wechselt, die neuen Programmierer nicht überfordert.

Welche Möglichkeiten gibt es in diesem Szenario, die Codebasen zu pflegen und synchron zu halten? Mit "Weg" meine ich Software-Tools, Best Practices usw.

Zu Ihrer Information, die beiden Sprachen sind C ++ und Java. C ++ für Windows / Linux und Java für "alles andere" einschließlich Android.


3
Müssen Sie es wirklich in einer anderen Sprache neu implementieren? Warum nicht einfach Java verwenden?
Oleksi

@Oleksi Der Code ist am besten, wenn er nativ ausgeführt wird. Java war also nur ein Kompromiss, bei dem C ++ nicht verwendet werden kann.
Vin

13
Stellen Sie einfach sicher, dass Sie diese Leistung benötigen. Das Verwalten von zwei Versionen eines Programms (insbesondere einer dieser komplexen) ist eine gewaltige Anstrengung. Stellen Sie sicher, dass Sie dies unbedingt in C ++ tun müssen, da Sie dafür viel Zeit und Mühe in zwei Sprachen aufwenden müssen.
Oleksi

9
Wie @Oleksi sagte - wenn es in Java auf einem Driod akzeptabel läuft, kann ich mir nicht vorstellen, dass C ++ die (wahrscheinlich geringfügigen) Verbesserungen benötigt, die der PC bietet. Da Sie nicht angegeben haben, dass Sie Leistungstests durchgeführt haben, gehe ich nicht davon aus. In diesem Fall stinkt dies nach vorzeitiger Optimierung. Schreiben Sie in Java, führen Sie Leistungstests durch und optimieren Sie Java. Nur dann sollten Sie eine C ++ - Umschreibung in Betracht ziehen - die Zeitersparnis bei der Verwaltung einer Codebasis, die stattdessen optimiert wird, führt mit ziemlicher Sicherheit dazu, dass zwei Codebasen und zwei Sätze von allem (mit Ausnahme der Anforderungen) verwaltet werden.
Mattnz

@thePrivateProject define läuft am besten , in jedem Fall (C ++ oder Java) sollte gut geschriebener Code portabel sein .

Antworten:


16

Kurze Antwort: Tun Sie dies nur, wenn Sie dazu gezwungen werden.

Wenn Sie C ++ verwenden müssen, können Sie das NDK verwenden , um Ihren Algorithmus für Android in C ++ zu erstellen, und dann einen dünnen Java-Wrapper für die Benutzeroberfläche hinzufügen. Beachten Sie, dass die Verwendung des NDK bedeutet, dass Ihr Code für verschiedene Arten von Hardware viel weniger portabel ist. Dies ist definitiv nicht der Verwendung von Java überall vorzuziehen, aber besser als zwei Codebasen.

Wenn Sie dies absolut nicht können und zwei Codebasen benötigen, finden Sie hier drei Vorschläge:

1) Suchen Sie nach einem Tool wie Unity, das auf tragbare Software ausgerichtet ist.

2) Versuchen Sie, die komplexen Teile des Codes in Daten oder eine Skriptsprache zu ziehen. Wenn Sie ziemlich allgemeinen Code schreiben können, um mit der Skriptsprache umzugehen, ist es einfacher, zweimal zu testen und richtig zu machen. (Insbesondere, wenn es sich um eine Standardsprache handelt, die von einer anderen Person erstellt wurde.) Dann können Sie eine Codebasis für die komplexen Bits haben. (Sie könnten Lua ausprobieren, das auf Einbettbarkeit ausgerichtet ist.)

3) Erstellen Sie, wie in der anderen Antwort angegeben, eine Testsuite, um beide Codesätze zu validieren. Beachten Sie, dass dies wirklich schwer zu korrigieren ist. Nachdem ich genau dies getan habe, kann ich Ihnen sagen, dass es viele Debatten darüber gibt, welche Version "richtig" ist, insbesondere in Fehlerfällen.

(2) und (3) können zusammen verwendet werden.


4
Gute Argumente. Eine andere Sache, über die man nachdenken sollte, ist das Schreiben eines Satzes von Regressionstests und das Testen beider Implementierungen damit (z. B. über SWIG).
James Youngman

15

Erstellen Sie eine einzelne externe Testsuite, mit der sichergestellt werden kann, dass sich beide Codebasen gleich verhalten. Ich lege besonderen Wert auf das Wort "Single", da Sie sonst zwei Testsuiten unterhalten müssen, die sich in ihren Behauptungen unterscheiden können. Ich habe keine Vorschläge dazu, aber es scheint eine Möglichkeit zu sein, Ihre (und die der zukünftigen Entwickler) Vernunft zu wahren, wenn Sie an dieser Art von Codebasis arbeiten.


4

Sie können eine Sprache verwenden, die entweder in Java- und C ++ - oder direkt in Maschinencode und Java-Bytecode kompiliert werden kann. Zuletzt habe ich überprüft, ob LLVM Backends für beide hat

Bearbeiten: Ein bisschen Wiki-Surfen brachte mich zu GCJ, das Java zu Maschinencode kompilieren kann


4

Meiner Meinung nach ist die wichtigste Regel für einen Programmierer "Wiederholen Sie sich nicht". Was Sie vorschlagen, ist ein klarer Verstoß gegen diese Regel.

Ich würde ernsthaft vorschlagen, dass Sie einen Weg finden, den Algorithmus nur einmal zu implementieren. Ich kann mir derzeit zwei verschiedene Ansätze vorstellen.

  • Verwenden Sie eine domänenspezifische Sprache. Möglicherweise kann der Algorithmus besser in einer anderen Sprache ausgedrückt werden, z. B. in einer Skriptsprache, für die auf allen Plattformen, auf denen die Anwendung ausgeführt werden soll, ein Parser vorhanden sein kann, oder Sie können C ++ / Java-Code basierend auf dem DSL-Code generieren.

  • Schreiben Sie alles in C ++. C ++ kann auf praktisch jeder Plattform kompiliert werden. Wenn auf einigen Plattformen die Hauptanwendung in Java geschrieben sein muss, ist es wahrscheinlich möglich, eine native Bibliothek aufzurufen (ich kenne mich in Java nicht sehr gut aus, gehe aber davon aus, dass dies möglich ist).

Die Beibehaltung des gleichen Algorithmus auf zwei verschiedenen Plattformen kann nur zu Schmerzen und Fehlern führen.


Ich nehme an, Ihrer Meinung nach sollte es ein Betriebssystem geben, ein Büro-Produktivitätsanzug, ein Video-Player-Softwarepaket ........
mattnz

1
@mattnz - Du hast meinen Standpunkt völlig falsch verstanden. Ich beziehe mich auf das Programmierprinzip von "DRY". Dieses Prinzip legt in keiner Weise nahe, dass es nur ein Betriebssystem, eine Office-Suite usw. geben sollte. Sie können problemlos ein Produkt für mehrere Plattformen erstellen, während Sie sich an DRY halten.
Pete

2

Zusätzlich zu den hervorragenden Ratschlägen zur Verwendung einer gemeinsamen externen Testsuite sollten Sie sich mit der Programmierkompetenz befassen . Mit literarischen Programmiertools können Sie mehrere Dateien aus einer einzigen Quelldatei erstellen.

Die traditionelle Verwendung von LP besteht darin, dass Sie die Dokumentation so mit Code verschachteln können, dass Sie die Dokumentation sehr nahe am Quellcode halten können. Eine einzelne Noweb- Datei (zum Beispiel) kann verwendet werden, um eine Dokumentationsdatei zu generieren, die mit (z. B.) LaTex zu einem größeren Dokument kompiliert werden kann, und eine .cppund- .hDatei zu erstellen, die in Ihre Anwendung kompiliert werden kann.

In Ihrem Fall können Sie möglicherweise sowohl die Codebasis als auch die Dokumentation zusammenhalten und auch eine .javaDatei erstellen.

Wenn Sie die Dokumentation und die verschiedenen Codeversionen in einer einzigen Datei zusammenhalten, die in logisch äquivalente Abschnitte unterteilt ist, sollte es viel einfacher sein, sie alle miteinander synchron zu halten.


2

Dies ist ein gutes Beispiel dafür, wo Tests hilfreich sein können.

Ich würde vorschlagen, eine einzige Testsuite zu haben, für die beide Codebasen ausgeführt werden. Dann wissen Sie, dass Ihre Codebasen beide der gleichen Spezifikation entsprechen!

(und gute Testabdeckung!)


1

Betrachten Sie den Code, der C ++ und Java aus einer anderen Sprache generiert


0

Haftungsausschluss

Wie bereits in früheren Beiträgen erwähnt, wenn Sie nicht wirklich eine andere Wahl haben, dann.

Antworten

Mehrere praktische Vorschläge anstelle einer einzigen Antwort:

(1) Verwenden Sie gemeinsame Strukturen, auch wenn die gleichen Aufgaben unterschiedlich ausgeführt werden können.

Beispiel: Ich musste den gleichen Code in "Object Pascal" & "C ++" haben, wobei der "if" -Satz in beiden vorhanden ist, die Klammer in "C ++" ist erforderlich, aber nicht in "object Pascal".

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

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

Gewechselt zu:

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

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

Beide Sprachen wurden in Klammern gesetzt. Ein weiterer Fall sind optionale Namespaces im Vergleich zu erforderlichen Namespaces ("Pakete").

(3) Beibehaltung der Bezeichnernamen, Groß- und Kleinschreibung, insbesondere der Typen, ähnlich, Verwendung von Aliasnamen, Unterklassen, Umhüllung:

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

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

// C++
// 
include <iostream>

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

In:

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

...

Zusammenfassung

Normalerweise muss ich mit mehreren Programmiersprachen arbeiten, und es gibt einige benutzerdefinierte "Kern" -Bibliotheken, die ich in mehreren Programmiersprachen behalte.

Viel Glück.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.