มีวิธีใดบ้างในการบำรุงรักษาโค้ดเบสที่เขียนในสองภาษาที่ใช้ตรรกะเดียวกัน


10

ฉันมีอัลกอริธึมเข้มข้นแบบลอจิคัลที่ฉันต้องการรหัสในสองภาษา (จริง ๆ แล้วฉันเสร็จในภาษาหนึ่งที่น่าพอใจและกำลังจะเริ่มเขียนโค้ดในภาษาอื่น) โดยความเข้มข้นของลอจิกผมหมายถึงอัลกอริทึมนั้นไม่สำคัญต้องมีความเข้าใจอย่างรอบคอบและที่สำคัญอาจมีข้อบกพร่อง (เนื่องจากความซับซ้อนและความประมาทคุณรู้) ซึ่งจะต้องได้รับการแก้ไขในอนาคต

นอกจากนี้ฉันต้องการตรวจสอบให้แน่ใจว่าเมื่อรหัสนี้เปลี่ยนมือในที่สุดจะต้องไม่ครอบงำโปรแกรมเมอร์ใหม่

ในสถานการณ์นี้วิธีใดบ้างที่จะช่วยรักษาฐานรหัสและทำให้ข้อมูลตรงกัน ฉันหมายถึงเครื่องมือซอฟต์แวร์แนวปฏิบัติที่ดีที่สุด ฯลฯ

FYI ทั้งสองภาษาคือ C ++ และ Java C ++ สำหรับ Windows / Linux และ Java สำหรับ "ทุกอย่างอื่น" รวมถึง Android


3
คุณต้องนำมันไปใช้ในภาษาอื่นหรือไม่? ทำไมไม่ใช้เพียง Java?
Oleksi

@Oleksi รหัสที่ดีที่สุดเมื่อมันทำงานโดยกำเนิดดังนั้น Java เป็นเพียงการประนีประนอมที่ C ++ ไม่สามารถใช้
vin

13
เพียงแค่ทำให้แน่ใจว่าคุณต้องการประสิทธิภาพนั้น การบำรุงรักษาโปรแกรมสองเวอร์ชัน (โดยเฉพาะที่ซับซ้อนนี้) เป็นความพยายามที่ยิ่งใหญ่ ตรวจสอบให้แน่ใจว่าคุณต้องทำสิ่งนี้อย่างแน่นอนใน C ++ เพราะคุณจะต้องเสียค่าใช้จ่ายมากในเวลาและความพยายามในการทำสองภาษา
Oleksi

9
ดังที่ @Oleksi กล่าวว่า - ถ้ามันทำงานได้อย่างเป็นที่ยอมรับใน Java บน Driod ฉันไม่สามารถจินตนาการได้เลยว่าเมื่อพีซีต้องการการปรับปรุง (อาจจะเล็กน้อย) C + + จะให้ ในขณะที่คุณไม่ได้ระบุว่าคุณได้ทำการทดสอบประสิทธิภาพฉันจึงไม่ถือว่าในกรณีนี้การเพิ่มประสิทธิภาพก่อนกำหนด เขียนเป็น Java เรียกใช้การทดสอบประสิทธิภาพเพิ่มประสิทธิภาพ Java จากนั้นให้พิจารณาการเขียน C ++ ใหม่ - เวลาที่บันทึกการบำรุงรักษาหนึ่งรหัสฐานใส่ optimaisation แทนเกือบจะแน่นอนจะดำเนินการบำรุงรักษาสองฐานรหัสสองชุดทุกอย่าง (ยกเว้นข้อกำหนด)
mattnz

@thePrivateProject กำหนดวิ่งที่ดีที่สุดทั้งในกรณีที่ (C ++ หรือ Java) รหัสเขียนดีควรจะพกพา

คำตอบ:


16

คำตอบสั้น ๆ : อย่าทำอย่างนี้นอกจากบังคับอย่างแน่นอน

หากคุณต้องใช้ C ++ คุณอาจพิจารณาใช้NDKเพื่อสร้างอัลกอริทึมของคุณสำหรับ Android ใน C ++ จากนั้นเพิ่ม Java wrapper แบบบางสำหรับ UI โปรดทราบว่าการใช้ NDK หมายความว่ารหัสของคุณสามารถพกพาได้น้อยลงไปยังฮาร์ดแวร์ประเภทต่างๆ สิ่งนี้ไม่เหมาะที่จะใช้ Java ในทุกที่ แต่ดีกว่าการมีรหัสสองฐาน

หากคุณไม่สามารถทำสิ่งนี้ได้อย่างสมบูรณ์และต้องมีรหัสสองฐานต่อไปนี้เป็นคำแนะนำสามข้อ:

1) ค้นหาเครื่องมืออย่างUnity ที่มีต่อซอฟต์แวร์พกพา

2) พยายามดึงบิตที่ซับซ้อนของรหัสลงในข้อมูลหรือภาษาสคริปต์บางอย่าง หากคุณสามารถเขียนรหัสทั่วไปที่ค่อนข้างเป็นธรรมเพื่อจัดการกับภาษาสคริปต์ได้ง่ายขึ้นในการทดสอบและทำให้ถูกต้องสองครั้ง (โดยเฉพาะถ้ามันเป็นภาษามาตรฐานที่คนอื่นสร้างขึ้น) จากนั้นคุณสามารถมี codebase หนึ่งอันสำหรับบิตที่ซับซ้อน (คุณอาจลอง Lua ซึ่งมุ่งสู่ความสามารถในการฝัง)

3) เช่นเดียวกับสถานะคำตอบอื่น ๆ ให้สร้างชุดทดสอบเพื่อตรวจสอบความถูกต้องของชุดรหัสทั้งสองชุด โปรดทราบว่านี่เป็นการยากที่จะทำให้ถูกต้อง หลังจากทำสิ่งนี้เสร็จแล้วฉันสามารถบอกคุณได้ว่ามีข้อถกเถียงมากมายเกี่ยวกับเวอร์ชันที่ "ถูกต้อง" โดยเฉพาะในกรณีที่เกิดข้อผิดพลาด

(2) และ (3) สามารถใช้ร่วมกันได้


4
จุดที่ดี สิ่งที่ต้องคิดอีกอย่างคือการเขียนการทดสอบการถดถอยหนึ่งชุดและทดสอบการใช้งานทั้งสองแบบ (เช่นผ่านทาง SWIG)
James Youngman

15

สร้างชุดทดสอบภายนอกชุดเดียวที่สามารถมั่นใจได้ว่าฐานรหัสทั้งสองทำงานในลักษณะเดียวกัน ฉันให้ความสำคัญเป็นพิเศษกับคำว่า "โสด" เพราะมิฉะนั้นคุณจะต้องรักษาชุดทดสอบสองชุดซึ่งอาจแตกต่างกันในการยืนยันของพวกเขา ฉันไม่มีคำแนะนำเกี่ยวกับวิธีการทำเช่นนี้ แต่ดูเหมือนว่าวิธีหนึ่งในการรักษาสติ (และนักพัฒนาในอนาคต) ของคุณเมื่อทำงานกับฐานรหัสประเภทนี้


4

คุณสามารถใช้ภาษาที่สามารถคอมไพล์เป็นรหัสเครื่องและโค้ดจาวาไบต์ทั้งก่อนโดยเปลี่ยนเป็นจาวาและ C ++ หรือโดยตรง ล่าสุดฉันตรวจสอบ LLVM มี back-end สำหรับทั้งสอง

แก้ไข: การท่องวิกิเล็กน้อยทำให้ฉันไปที่GCJซึ่งสามารถคอมไพล์จาวากับโค้ดของเครื่อง


4

ในความคิดของฉันกฎที่สำคัญที่สุดสำหรับโปรแกรมเมอร์คือ "อย่าทำซ้ำตัวเอง" สิ่งที่คุณแนะนำคือการละเมิดกฎนี้อย่างชัดเจน

ฉันขอแนะนำอย่างจริงจังให้คุณหาวิธีที่จะใช้อัลกอริทึมเพียงครั้งเดียว ปัจจุบันฉันสามารถนึกถึงวิธีการที่แตกต่างกันสองวิธี

  • ใช้ภาษาเฉพาะโดเมน บางทีอัลกอริทึมอาจแสดงได้ดีกว่าในภาษาอื่นเช่นภาษาสคริปต์ซึ่ง parser อาจมีอยู่บนแพลตฟอร์มทั้งหมดที่คุณคาดว่าจะเรียกใช้แอปพลิเคชันหรือคุณสามารถสร้างรหัส C ++ / Java ตามรหัส DSL

  • เขียนทุกอย่างใน C ++ C ++ สามารถคอมไพล์กับแทบทุกแพลตฟอร์ม หากในบางแพลตฟอร์มที่คุณต้องการให้เขียนแอปพลิเคชันหลักใน Java ฉันจะเดาว่าเป็นไปได้ที่จะเรียกไลบรารี่เนทีฟ (ฉันไม่ค่อยรู้เรื่อง Java แต่ฉันคิดว่ามันสามารถทำได้)

การรักษาอัลกอริทึมที่เหมือนกันในสองแพลตฟอร์มที่แตกต่างกันสามารถนำไปสู่ความเจ็บปวดและข้อบกพร่องเท่านั้น


ฉันคิดว่าโดยความเห็นของคุณควรมีระบบปฏิบัติการหนึ่งระบบในชุดเพิ่มประสิทธิภาพสำนักงานชุดซอฟต์แวร์เครื่องเล่นวิดีโอหนึ่งชุด ........
mattnz

1
@mattnz - คุณเข้าใจผิดในประเด็นของฉันอย่างเต็มที่ ฉันหมายถึงหลักการเขียนโปรแกรมของ "DRY" หลักการดังกล่าวไม่ได้ชี้แนะว่าควรมีระบบปฏิบัติการเดียวเท่านั้นชุดสำนักงานและอื่น ๆ คุณสามารถผลิตผลิตภัณฑ์สำหรับหลายแพลตฟอร์มได้อย่างง่ายดายขณะที่ติด DRY
Pete

2

นอกจากคำแนะนำที่ยอดเยี่ยมในการใช้ ชุดทดสอบภายนอกทั่วไปคุณอาจต้องการที่จะมองเข้าไปในการเขียนโปรแกรมความรู้ เครื่องมือการเขียนโปรแกรมความรู้ช่วยให้คุณสามารถสร้างไฟล์หลายไฟล์จากไฟล์ต้นฉบับไฟล์เดียว

การใช้ LP แบบดั้งเดิมคือการอนุญาตให้คุณแทรกเอกสารด้วยรหัสในลักษณะที่ช่วยให้คุณเก็บเอกสารไว้ใกล้กับซอร์สโค้ดมาก สามารถใช้ไฟล์nowebเดียว(ตัวอย่าง) เพื่อสร้างไฟล์ documenation ซึ่งสามารถรวบรวมเป็นเอกสารขนาดใหญ่โดยใช้ (พูด) LaTex และสร้าง a .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)
{
  ...
}
...

เพิ่มวงเล็บให้ทั้งสองภาษา อีกกรณีจะเป็นเนมสเปซทางเลือกและเนมสเปซที่ต้องการ ("แพ็คเกจ")

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