Một số cách để duy trì các cơ sở mã được viết bằng hai ngôn ngữ thực hiện cùng một logic là gì?


10

Tôi có một thuật toán chuyên sâu logic mà tôi cần mã hóa bằng hai ngôn ngữ (thực ra tôi đã hoàn thành nó bằng một ngôn ngữ một cách thỏa đáng và sắp bắt đầu viết mã bằng ngôn ngữ khác). Theo logic chuyên sâu, ý tôi là thuật toán này không tầm thường, cần sự hiểu biết cẩn thận và quan trọng là có thể có lỗi (do sự phức tạp và bất cẩn, bạn biết) sẽ phải được vá trong tương lai.

Ngoài ra, tôi muốn chắc chắn rằng khi mã này đổi tay, cuối cùng, nó không được áp đảo các lập trình viên mới.

Với kịch bản này, một số cách sẽ giúp duy trì các cơ sở mã và giữ chúng đồng bộ là gì? Theo cách tôi có nghĩa là các công cụ phần mềm, thực hành tốt nhất, vv

FYI hai ngôn ngữ là C ++ và Java. C ++ cho Windows / Linux và Java cho "mọi thứ khác" bao gồm cả Android.


3
Bạn có thực sự phải thực hiện lại nó trong ngôn ngữ khác? Tại sao không sử dụng chỉ Java?
Oleksi

@Oleksi Mã là tốt nhất khi nó chạy tự nhiên vì vậy Java chỉ là một sự thỏa hiệp trong đó C ++ không thể được sử dụng.
vin

13
Chỉ cần chắc chắn rằng bạn cần hiệu suất đó. Duy trì hai phiên bản của một chương trình (đặc biệt là một phức tạp này), là một nỗ lực khổng lồ. Hãy chắc chắn rằng bạn hoàn toàn cần phải làm điều này trong C ++, bởi vì bạn sẽ phải trả một khoản chi phí rất lớn về thời gian và công sức để làm điều này bằng hai ngôn ngữ.
Oleksi

9
Như @Oleksi đã nói - nếu nó chạy chấp nhận được trong Java trên Driod, tôi không thể tưởng tượng được rằng PC cần những cải tiến (có thể là cận biên) mà C ++ sẽ cung cấp. Như bạn đã không nói rằng bạn đã chạy thử nghiệm hiệu suất, tôi giả sử là không, trong trường hợp này, mùi hôi thối của tối ưu hóa sớm. Viết bằng Java, chạy thử nghiệm hiệu năng, tối ưu hóa Java. Chỉ sau đó xem xét viết lại C ++ - thời gian lưu duy trì một cơ sở mã, thay vào đó là tối ưu hóa, gần như chắc chắn sẽ thực hiện duy trì hai cơ sở mã, hai bộ mọi thứ (trừ yêu cầu).
mattnz

@thePrivateProject xác định chạy tốt nhất , trong cả hai trường hợp (C ++ hoặc Java) mã được viết tốt nên có thể mang theo được .

Câu trả lời:


16

Câu trả lời ngắn: không làm điều này trừ khi hoàn toàn bị ép buộc.

Nếu bạn phải sử dụng C ++, thì bạn có thể cân nhắc sử dụng NDK để xây dựng thuật toán cho Android trong C ++ và sau đó thêm vào một trình bao bọc Java mỏng cho UI. Lưu ý rằng việc sử dụng NDK có nghĩa là mã của bạn ít di động hơn đối với các loại phần cứng khác nhau. Điều này chắc chắn không thích sử dụng Java ở mọi nơi, nhưng tốt hơn là có hai cơ sở mã.

Nếu bạn hoàn toàn không thể làm điều này và phải có hai cơ sở mã, đây là ba gợi ý:

1) Tìm kiếm một công cụ như Unity hướng đến phần mềm di động.

2) Cố gắng kéo các bit phức tạp của mã vào dữ liệu hoặc một số ngôn ngữ kịch bản lệnh. Nếu bạn có thể viết mã khá chung chung để đối phó với ngôn ngữ kịch bản, việc kiểm tra và lấy đúng hai lần sẽ dễ dàng hơn. (Đặc biệt nếu đó là một ngôn ngữ tiêu chuẩn được tạo bởi người khác.) Sau đó, bạn có thể có một cơ sở mã cho các bit phức tạp. (Bạn có thể thử Lua, hướng đến khả năng nhúng.)

3) Như các trạng thái trả lời khác, tạo bộ kiểm tra để xác thực cả hai bộ mã. Lưu ý rằng điều này thực sự khó để có được đúng. Đã thực hiện chính xác điều này, tôi có thể nói với bạn rằng nó cần nhiều cuộc tranh luận về phiên bản nào là "đúng", đặc biệt là trong các trường hợp lỗi.

(2) và (3) có thể được sử dụng cùng nhau.


4
Điểm tốt. Một điều khác cần suy nghĩ là viết một tập các bài kiểm tra hồi quy và kiểm tra cả hai triển khai với nó (ví dụ thông qua SWIG).
James Youngman

15

Xây dựng một bộ kiểm thử bên ngoài duy nhất có thể đảm bảo cả hai cơ sở mã hoạt động theo cùng một cách. Tôi nhấn mạnh thêm vào từ "độc thân" bởi vì nếu không, bạn sẽ phải duy trì hai bộ thử nghiệm có thể khác nhau trong các xác nhận của chúng. Tôi không có bất kỳ đề xuất nào về cách thực hiện việc này, nhưng có vẻ như là một cách để duy trì sự tỉnh táo của bạn (và các nhà phát triển trong tương lai) khi làm việc trên loại cơ sở mã này.


4

bạn có thể sử dụng một ngôn ngữ có thể biên dịch thành mã máy và mã byte java bằng cách trước tiên chuyển đổi thành java và C ++ hoặc trực tiếp. Lần cuối tôi kiểm tra LLVM có back-end cho cả hai

chỉnh sửa: một chút lướt wiki đã đưa tôi đến với GCJ có thể biên dịch java thành mã máy


4

Theo tôi, quy tắc quan trọng nhất đối với một lập trình viên là "Đừng lặp lại chính mình". Những gì bạn đề nghị là một sự vi phạm rõ ràng của quy tắc này.

Tôi thực sự khuyên bạn nên tìm cách chỉ thực hiện thuật toán một lần. Hiện tại tôi có thể nghĩ về hai cách tiếp cận khác nhau.

  • Sử dụng một ngôn ngữ cụ thể miền. Có lẽ thuật toán có thể được thể hiện tốt hơn bằng một ngôn ngữ khác, ví dụ ngôn ngữ tập lệnh, trong đó trình phân tích cú pháp có thể tồn tại trên tất cả các nền tảng mà bạn muốn chạy ứng dụng hoặc bạn có thể tạo mã C ++ / Java dựa trên mã DSL.

  • Viết mọi thứ bằng C ++. C ++ có thể được biên dịch cho hầu hết mọi nền tảng. Nếu trên một số nền tảng bạn yêu cầu ứng dụng chính được viết bằng Java, tôi đoán rằng có thể gọi một thư viện riêng (tôi không rành về Java, nhưng tôi cho rằng có thể thực hiện được).

Việc duy trì cùng một thuật toán trên hai nền tảng khác nhau chỉ có thể dẫn đến đau đớn và lỗi.


Tôi cho rằng theo ý kiến ​​của bạn thì nên có một hệ điều hành, phù hợp với năng suất văn phòng, một gói phần mềm trình phát video ........
mattnz

1
@mattnz - Bạn đã hoàn toàn hiểu sai quan điểm của tôi. Tôi đang đề cập đến nguyên tắc lập trình của "DRY". Nguyên tắc đó không có cách nào cho thấy rằng chỉ nên có một hệ điều hành, bộ ứng dụng văn phòng, v.v. Bạn có thể dễ dàng sản xuất một sản phẩm cho nhiều nền tảng trong khi gắn bó với DRY.
Pete

2

Ngoài những lời khuyên tuyệt vời để sử dụng một bộ kiểm tra bên ngoài phổ biến, bạn có thể muốn xem xét lập trình biết chữ . Các công cụ lập trình biết chữ cung cấp cho bạn khả năng tạo nhiều tệp từ một tệp nguồn duy nhất.

Cách sử dụng LP truyền thống là cho phép bạn xen kẽ tài liệu với mã theo cách cho phép bạn giữ tài liệu rất gần với mã nguồn. Một đơn noweb tập tin (ví dụ) có thể được sử dụng để tạo ra một file documenation có thể được biên dịch vào một tài liệu lớn sử dụng (nói) LaTex, và sản xuất một .cpp.htập tin có thể được biên dịch vào ứng dụng của bạn.

Trong trường hợp của bạn, nó có thể cho phép bạn giữ cả hai cơ sở mã và tài liệu cùng nhau, tạo ra một .javatệp.

Giữ tài liệu và các phiên bản mã khác nhau trong một tệp duy nhất, được chia thành các phần tương đương logic, sẽ giúp việc giữ tất cả chúng đồng bộ với nhau dễ dàng hơn nhiều .


2

Đây là một ví dụ tốt về nơi các bài kiểm tra có thể hữu ích.

Tôi sẽ đề nghị có một bộ kiểm tra duy nhất mà cả cơ sở mã của bạn chạy cùng. Sau đó, bạn biết rằng mã của bạn căn cứ cả hai phù hợp với cùng một đặc điểm kỹ thuật!

(và, có phạm vi kiểm tra tốt!)



0

Khước từ

Như đã đề cập trước đó, bài viết, nếu bạn không thực sự có lựa chọn khác, sau đó.

Câu trả lời

Một số gợi ý thiết thực, thay vì một câu trả lời duy nhất:

(1) Sử dụng các cấu trúc phổ biến, thậm chí, nếu cùng một công cụ có thể được thực hiện khác nhau.

Ví dụ: Tôi phải có cùng một mã trong "Object Pascal" & "C ++", trong đó câu "if" tồn tại trong cả hai, dấu ngoặc đơn trong "C ++" là bắt buộc, nhưng, không phải trong "object Pascal".

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

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

Thay đổi để:

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

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

Đã thêm dấu ngoặc đơn cho cả hai ngôn ngữ. Một trường hợp khác sẽ là không gian tên tùy chọn so với không gian tên được yêu cầu ("gói").

(3) Giữ tên định danh, độ nhạy trường hợp, loại đặc biệt, tương tự, sử dụng bí danh, phân lớp, gói:

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

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

// C++
// 
include <iostream>

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

Vào:

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

...

Tóm lược

Tôi thường phải làm việc với một số ngôn ngữ lập trình và có một số thư viện "lõi" tùy chỉnh mà tôi giữ trong một số ngôn ngữ lập trình.

Chúc may mắn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.