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


10

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

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

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

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


3
本当に別の言語で再実装する必要がありますか?Javaだけを使用しないのはなぜですか?
Oleksi、2012年

@Oleksiコードはネイティブで実行する場合に最適であるため、JavaはC ++を使用できない妥協案にすぎません。
vin

13
そのパフォーマンスが必要であることを絶対に確認してください。プログラムの2つのバージョン(特にこの複雑なバージョンの1つ)を維持することは、巨大な取り組みです。これをC ++で絶対に行う必要があることを確認してください。これは、2つの言語でこれを行うために多大な時間と労力を費やすことになるためです。
Oleksi

9
@Oleksiが言ったように-それがDriod上のJavaで許容範囲内で実行される場合、PCがC ++に与える(おそらく限界的な)改善が必要であるとは想像できません。あなたがあなたがパフォーマンステストを実行したと述べなかったので、私はそうではないと思います、その場合、これは時期尚早な最適化の悪臭を放ちます。Javaで記述し、パフォーマンステストを実行し、Javaを最適化します。次に、C ++の書き換えを検討します。代わりに1つのコードベースを維持して節約した時間を最適化にすると、ほぼ確実に2つのコードベース、2つのセットすべて(要件を除く)を維持できます。
mattnz 2012年

@thePrivateProject define 、どちらの場合(C ++またはJava)でも適切に記述されたコードを移植できるように実行するのが最適です。

回答:


16

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

C ++を使用する必要がある場合は、NDKを使用してC ++でAndroid用のアルゴリズムを構築し、UIのシンJavaラッパーを追加することを検討してください。NDKを使用すると、コードがさまざまな種類のハードウェアに移植できなくなることに注意してください。これは、どこでもJavaを使用するよりも明らかに好ましい方法ではありませんが、2つのコードベースを使用するよりは優れています。

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

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

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

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

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


4
良い点。もう1つ考えるべきことは、1セットの回帰テストを作成し、それを使用して両方の実装を(たとえばSWIGを介して)テストすることです。
ジェームズヤングマン

15

両方のコードベースが同じように動作することを確認できる単一の外部テストスイートを構築します。「単一」という言葉を特に強調します。そうしないと、アサーションが異なる2つのテストスイートを維持する必要があるためです。これを行う方法についての提案はありませんが、これは、この種のコードベースで作業するときにあなた(および将来の開発者)の健全性を維持する1つの方法のようです。


4

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

編集:ちょっとしたウィキサーフィンでJavaをマシンコードにコンパイルできるGCJに行きました


4

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

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

  • ドメイン固有の言語を使用します。おそらく、アルゴリズムを別の言語(スクリプト言語など)でより適切に表現することができます。そのため、アプリケーションを実行する予定のすべてのプラットフォームにパーサーが存在するか、DSLコードに基づいてC ++ / Javaコードを生成できます。

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

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


あなたの意見では、1つのオペレーティングシステム、オフィスの生産性訴訟、1つのビデオプレーヤーソフトウェアパッケージが必要だと思います
。..–

1
@mattnz-あなたは私のポイントを完全に誤解しています。「DRY」のプログラミング原理を参考にしています。この原則は、オペレーティングシステム、オフィススイートなどが1つだけであることを決して示唆していません。DRYを使用している間、複数のプラットフォーム用の製品を簡単に作成できます。
ピート

2

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

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

あなたの場合、それはあなたがコードベースとドキュメントの両方を一緒にして.javaファイルを生成することを可能にするかもしれません。

ドキュメントと異なるコードバージョンを1つのファイルにまとめて、論理的に同等のセクションに分割すると、それらすべてを互いに同期させることがはるかに簡単になります。


2

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

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

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



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

...

概要

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

幸運を。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.