web-dev-qa-db-ja.com

同じロジックを実装する2つの言語で書かれたコードベースを維持する方法は何ですか?

2つの言語でコーディングする必要があるロジック集約型のアルゴリズムがあります(実際には1つの言語で問題なく終了し、もう1つの言語でコーディングを開始しようとしています)。ロジック集約型とは、アルゴリズムが重要であり、注意深く理解する必要があり、さらに重要なことには、将来パッチを適用する必要のあるバグ(複雑さと不注意のため)が存在する可能性があることを意味します。

また、このコードが変更されたときに、最終的には新しいプログラマーを圧倒してはならないことを確認したいと思います。

このシナリオを前提として、コードベースを維持して同期を保つのに役立ついくつかの方法は何ですか?ソフトウェアツール、ベストプラクティスなどを意味します。

参考までに、2つの言語はC++とJavaです。 C++ for Windows/LinuxおよびJava for Androidを含む「その他すべて」の場合。

10
vin

短い答え:絶対に強制されない限り、これを行わないでください。

C++を使用する必要がある場合は、 [〜#〜] ndk [〜#〜] を使用してAndroidのアルゴリズムをC++で構築し、次に細いJavaラッパーを追加します。NDKを使用すると、コードがさまざまな種類のハードウェアに移植しにくくなることに注意してください。これは、Javaどこでもですが、2つのコードベースよりも優れています。

これが絶対にできず、2つのコードベースが必要な場合は、次の3つの提案があります。

1) nity のようなポータブルソフトウェア向けのツールを探します。

2)コードの複雑なビットをデータまたは何らかのスクリプト言語にプルしようとします。スクリプト言語を扱うためのかなり一般的なコードを書くことができれば、テストして2回正しく実行する方が簡単です。 (特に、それが他の誰かによって作成された標準言語である場合。)次に、複雑なビット用に1つのコードベースを持つことができます。 (埋め込み可能に向けられたLuaを試してみてください。)

3)他の回答のように、両方のコードセットを検証するテストスイートを作成します。これを正しく行うのは本当に難しいことに注意してください。これを正確に行うと、特にエラーの場合に、どのバージョンが「正しい」かについての多くの議論に頼っていることがわかります。

(2)と(3)は併用できます。

16
Gort the Robot

両方のコードベースが同じように動作することを確認できるsingle外部テストスイートをビルドします。それ以外の場合は、アサーションが異なる可能性のあるtwoテストスイートを維持する必要があるため、私はWordの「単一」に特に重点を置きます。これを行う方法についての提案はありませんが、これは、この種のコードベースで作業するときにあなた(および将来の開発者)の健全性を維持する1つの方法のようです。

15
Jeremy Heiler

最初にJavaおよびC++に変換するか、直接変換することにより、マシンコードとJavaバイトコードにコンパイルできる言語を使用できます。最後に、LLVMが-両方の終わり

編集:少しのWikiサーフィンで [〜#〜] gcj [〜#〜] にコンパイルできましたJavaマシンコードにコンパイルできます

4
ratchet freak

私の意見では、プログラマーにとって最も重要なルールは、「自分を繰り返さない」です。あなたが提案するのは、このルールの明らかな違反です。

アルゴリズムを1回だけ実装する方法を見つけることを強くお勧めします。現在、私は2つの異なるアプローチを考えることができます。

  • ドメイン固有の言語を使用します。多分、アルゴリズムは別の言語でよりよく表現できるかもしれません。アプリケーションを実行する予定のすべてのプラットフォームにパーサーが存在するスクリプト言語、またはDSLコードに基づいてC++/Javaコードを生成できます。

  • すべてをC++で記述します。 C++は、事実上すべてのプラットフォームにコンパイルできます。一部のプラットフォームでメインアプリケーションをJavaで作成する必要がある場合は、ネイティブライブラリを呼び出すことができると思います(Javaについてはあまり詳しくありませんが、できると思います)。

2つの異なるプラットフォームで同じアルゴリズムを維持することは、苦痛とバグにつながるだけです。

4
Pete

一般的な外部テストスイート を使用するための優れたアドバイスに加えて、 リテラルプログラミング を調べることをお勧めします。識字率の高いプログラミングツールを使用すると、単一のソースファイルから複数のファイルを作成できます。

LPの従来の使用法は、ソースコードにドキュメントを非常に近くに保つことができる方法で、ドキュメントとコードをインターリーブできるようにすることです。単一の noweb ファイル(たとえば)を使用して、(たとえば)LaTexを使用してより大きなドキュメントにコンパイルできるドキュメントファイルを生成し、.cppおよび.hアプリケーションにコンパイルできるファイル。

あなたの場合、コードベースとドキュメントの両方を一緒にして、.Javaファイルも。

ドキュメントと異なるコードバージョンを1つのファイルにまとめ、論理的に同等のセクションに分割すると、すべてのファイルとの同期を維持しやすくなりますお互い。

2
Mark Booth

これは、テストが役立つ場合の良い例です。

両方コードベースが実行される単一のテストスイートを用意することをお勧めします。これで、コードベースが両方とも同じ仕様に準拠していることがわかります。

(そして、十分なテストカバレッジを持っています!)

2
user1249

C++およびJava他の言語からのコードを生成するコードを検討してください。

1
Nick Keighley

免責事項

以前に述べたように、投稿、本当に他に選択肢がない場合は、.

回答

単一の回答ではなく、いくつかの実用的な提案:

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

...

概要

私は通常、いくつかのプログラミング言語を使用する必要があり、いくつかのカスタム「コア」ライブラリーがいくつかあり、それらをいくつかのプログラミング言語で保持しています。

幸運を。

0
umlcat