동일한 논리를 구현하는 두 가지 언어로 작성된 코드베이스를 유지 관리하는 몇 가지 방법은 무엇입니까?


10

두 가지 언어로 코딩 해야하는 논리 집약적 알고리즘이 있습니다 (실제로 한 언어로 만족스럽게 완성하고 다른 언어로 코딩을 시작하려고합니다). 논리 집약적으로 나는 알고리즘이 사소한 것이 아니며 신중한 이해가 필요하며, 중요하게는 미래에 패치되어야 할 버그 (복잡성과 부주의로 인해)를 가질 수 있음을 의미합니다.

또한이 코드가 바뀌면 새로운 프로그래머를 압도해서는 안됩니다.

이 시나리오에서 코드베이스를 유지 관리하고 동기화하는 데 도움이되는 몇 가지 방법은 무엇입니까? 소프트웨어 툴, 모범 사례 등을 의미합니다.

참고로 두 언어는 C ++과 Java입니다. Windows / Linux 용 C ++ 및 Android를 포함한 "기타"용 Java.


3
다른 언어로 다시 구현해야합니까? 왜 Java 만 사용하지 않습니까?
Oleksi

@Oleksi 코드는 기본적으로 실행될 때 가장 좋으므로 Java는 C ++을 사용할 수없는 절충안이었습니다.
vin

13
그 성능이 필요한지 확인하십시오. 프로그램의 두 가지 버전 (특히이 복잡한 버전)을 유지 관리하는 것은 엄청난 노력입니다. 당신이 확인 절대적으로 당신의 시간과 두 개의 언어에서이 작업을 수행하기위한 노력의 일환으로 엄청난 비용을 지불하려고하기 때문에, C ++에서이 작업을 수행해야합니다.
Oleksi

9
@Oleksi가 말했듯이 Driod에서 Java로 받아 들일 수 있다면 PC에서 C ++이 줄 수있는 (아마도) 개선이 필요하다고 상상할 수 없습니다. 성능 테스트를 실행했다고 말하지 않았지만,이 경우 조기 최적화에 악영향을 미치지 않습니다. Java로 작성하고 성능 테스트를 실행하며 Java를 최적화하십시오. 그런 다음 C ++ 다시 쓰기를 고려하십시오. 하나의 코드베이스를 유지 관리하는 대신 시간을 절약하면 최적화에 투입되어 두 가지 코드베이스, 두 가지 세트 (모든 요구 사항 제외)를 유지 관리 할 수 ​​있습니다.
mattnz

@thePrivateProject define 은 가장 잘 실행되며 , 두 경우 모두 (C ++ 또는 Java) 잘 작성된 코드 는 이식 가능해야합니다 .

답변:


16

짧은 대답 : 절대로 강요하지 않는 한 이것을하지 마십시오.

C ++를 사용해야하는 경우 NDK 를 사용하여 C ++에서 Android 용 알고리즘을 빌드 한 다음 UI 용으로 얇은 Java 랩퍼를 추가 할 수 있습니다. NDK를 사용한다는 것은 코드가 다른 종류의 하드웨어에 비해 이식성이 훨씬 떨어진다는 것을 의미합니다. 이것은 어느 곳에서나 Java를 사용하는 것보다 바람직하지 않지만 두 개의 코드 기반을 갖는 것보다 낫습니다.

이 작업을 수행 할 수없고 두 개의 코드 기반이 있어야하는 경우 다음 세 가지 제안 사항이 있습니다.

1) 휴대용 소프트웨어에 적합한 Unity 와 같은 도구를 찾으십시오 .

2) 복잡한 코드 비트를 데이터 또는 일부 스크립팅 언어로 가져 오십시오. 스크립팅 언어를 처리하기 위해 상당히 일반적인 코드를 작성할 수 있으면 테스트하고 두 번 더 쉽게 얻을 수 있습니다. (특히 다른 사람이 만든 표준 언어 인 경우) 복잡한 비트에 대해 하나의 코드베이스를 가질 수 있습니다. (임베디드 가능성에 맞춰진 Lua를 사용해 볼 수 있습니다.)

3) 다른 답변에서 알 수 있듯이 테스트 코드를 작성하여 두 코드 세트를 모두 검증하십시오. 이것은 실제로 제대로 이해하기 어렵습니다. 정확히이 작업을 수행 한 후 특히 오류가 발생하는 경우 어떤 버전이 "올바른"것인지에 대한 많은 논쟁이 제기된다고 말할 수 있습니다.

(2)와 (3)을 함께 사용할 수 있습니다.


4
좋은 지적입니다. 고려해야 할 또 다른 사항은 한 세트의 회귀 테스트를 작성하고 두 가지 구현을 모두 테스트하는 것입니다 (예 : SWIG를 통해).
James Youngman

15

두 코드베이스가 동일한 방식으로 작동 할 수 있는 단일 외부 테스트 스위트를 빌드하십시오 . "단일"이라는 단어에 특히 중점을 두었습니다. 그렇지 않으면 어설 션이 다를 수있는 두 개의 테스트 스위트 를 유지해야하기 때문 입니다. 이 작업을 수행하는 방법에 대한 제안은 없지만 이런 종류의 코드 기반 작업을 할 때 (그리고 미래 개발자의) 정신을 유지하는 한 가지 방법처럼 보입니다.


4

먼저 java 및 C ++로 변환하거나 직접 기계 코드 및 Java 바이트 코드로 컴파일 할 수있는 언어를 사용할 수 있습니다. 마지막으로 LLVM에 백엔드가 있는지 확인했습니다.

편집 : 약간의 Wiki 서핑으로 Java를 기계 코드로 컴파일 할 수있는 GCJ에 도달했습니다.


4

제 생각에는 프로그래머에게 가장 중요한 규칙은 "반복하지 마십시오"입니다. 제안한 것은이 규칙을 명백히 위반하는 것입니다.

알고리즘을 한 번만 구현할 수있는 방법을 찾는 것이 좋습니다. 현재 두 가지 접근 방식을 생각할 수 있습니다.

  • 도메인 별 언어를 사용하십시오. 알고리즘이 다른 언어 (예 : 스크립트 언어)로 더 잘 표현 될 수 있습니다. 스크립트 언어는 응용 프로그램을 실행할 것으로 예상되는 모든 플랫폼에 파서가 있거나 DSL 코드를 기반으로 C ++ / Java 코드를 생성 할 수 있습니다.

  • C ++로 모든 것을 작성하십시오. C ++은 거의 모든 플랫폼으로 컴파일 할 수 있습니다. 일부 플랫폼에서 기본 응용 프로그램을 Java로 작성 해야하는 경우 기본 라이브러리를 호출하는 것이 가능하다고 생각합니다 (Java에 대해서는 잘 모르지만 수행 할 수 있다고 가정합니다).

서로 다른 두 플랫폼에서 동일한 알고리즘을 유지하면 고통과 버그만 발생할 수 있습니다.


나는 당신의 의견으로는 하나의 운영 체제, 사무실 생산성 정장, 하나의 비디오 플레이어 소프트웨어 패키지가 있어야한다고 생각합니다 ...
mattnz

1
@ mattnz-당신은 내 요점을 완전히 오해했습니다. "DRY"의 프로그래밍 원리를 언급하고 있습니다. 이러한 원칙에 따라 운영 체제, 사무실 제품군 등이 하나만 있어야한다는 것은 아닙니다. DRY를 고수하면서 여러 플랫폼 용 제품을 쉽게 생산할 수 있습니다.
Pete

2

일반적인 외부 테스트 슈트 를 사용하라는 훌륭한 조언 외에도 읽고 쓸 줄 아는 프로그래밍 을 살펴볼 수있다 . Literate Programming Tools를 사용하면 단일 소스 파일에서 여러 파일을 생성 할 수 있습니다.

LP의 전통적인 사용은 문서를 소스 코드에 매우 가깝게 유지할 수있는 방식으로 코드와 함께 문서를 인터리브 할 수 있도록하는 것 입니다. 예를 들어, 하나의 noweb 파일은 LaTex를 사용하여 더 큰 문서로 컴파일 할 수있는 문서 파일을 생성하고 응용 프로그램으로 컴파일 할 수 있는 .cpp.h파일을 생성하는 데 사용될 수 있습니다.

귀하의 경우 코드베이스와 문서를 함께 보관하여 .java파일을 생성 할 수 있습니다.

문서와 다른 코드 버전을 단일 파일로 논리적으로 동등한 섹션으로 분류 하면 서로 동기화하기가 훨씬 쉬워집니다.


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)
{
  ...
}
...

두 언어 모두에 괄호를 추가했습니다. 또 다른 경우는 선택적 네임 스페이스와 필수 네임 스페이스 ( "packages")입니다.

(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.