2012-08-02 40 views
5

Đây là câu hỏi chung "noob" về thiết kế phần mềm, vì vậy tôi xin lỗi nếu nó có vẻ mơ hồ, nhưng tôi thực sự sẽ đánh giá cao lời khuyên. Lưu ý rằng hệ thống được mô tả dưới đây hoàn toàn là một ví dụ, không phải là một sản phẩm cụ thể mà tôi có trong đầu.Sử dụng IPC để kết hợp nhiều ngôn ngữ

Tôi thường có nhu cầu kết hợp chức năng của một số thư viện hoặc tiện ích, được viết bằng các ngôn ngữ khác nhau. Ví dụ, nếu tôi muốn viết mã một ứng dụng xử lý âm thanh hiệu năng cao cho máy tính để bàn, tôi sẽ viết nó trong C/C++. Sau đó, tôi muốn thêm một giao diện đẹp. Nhưng tôi không muốn học Qt. Tôi thích giao diện của Adobe Air và muốn sử dụng nó. Sau đó, tôi có nhu cầu truy cập thiết bị USB. Nhưng thư viện USB tôi chỉ có một API trong Java. Làm thế nào tôi có thể kết hợp tất cả các yếu tố này với nhau, để tận dụng lợi thế của các thế mạnh tương đối của chúng?

Rõ ràng, tôi không thể biên dịch các thành phần khác nhau này thành một tệp thực thi duy nhất. Vì vậy, tôi cần phải tạo và chạy chúng một cách riêng biệt, và cung cấp cho họ một phương tiện để giao tiếp. Cách phổ biến nhất để làm điều này dường như đang sử dụng IPC (Inter Process Communication), ví dụ như bộ nhớ hoặc ổ cắm chung. Tôi thích ý tưởng của ổ cắm, như các chương trình có khả năng có thể chạy trên máy riêng biệt trên mạng.

Vì vậy, tôi quyết định tạo hệ thống máy khách/máy chủ cục bộ, với API tùy chỉnh, để cho phép các yếu tố này giao tiếp. Ví dụ, ứng dụng Air sẽ nhận được một tin nhắn từ ứng dụng C, yêu cầu nó cập nhật giao diện người dùng của nó. Ứng dụng USB chạy trong Java sẽ sử dụng các ổ cắm để truyền âm thanh từ phần cứng USB, vào ứng dụng C.

Câu hỏi của tôi: đang sử dụng ổ cắm cục bộ theo cách này một cách điển hình để thiết kế một hệ thống như vậy? Hiệu suất sẽ tồi tệ hơn nhiều so với ứng dụng gốc thực sự (ví dụ: mọi thứ trong Java hoặc C, trong một tệp thực thi duy nhất)? Nó cũng dường như có khả năng rằng một cách tiếp cận như vậy sẽ dễ bị lỗi, và khó khăn để duy trì?

Tôi thường thấy mình gặp phải các giới hạn của thư viện phần mềm hiện tại (ví dụ: thư viện đồ họa có giao diện người dùng khá linh hoạt nhưng không có cách nào để truy cập phần cứng cấp thấp hoặc thư viện phương tiện có thể kết hợp nhiều luồng âm thanh không hỗ trợ phát lại video) và thấy nó rất bực bội. Nếu bất cứ ai có thể tư vấn cho cách tốt nhất để kết hợp các thư viện phần mềm tùy ý như thế này, tôi thực sự sẽ đánh giá cao nó.

Cảm ơn trước!

Trả lời

4

Như bạn đã xác định chính xác, việc kết hợp các thư viện từ ngôn ngữ hoặc nền tảng khác nhau là khó. Có một số cách để làm điều đó, nhưng không có cách nào là lý tưởng. Ví dụ:

  • Giao diện cuộc gọi gốc (ví dụ: JNI/JNA) - rất nhanh nhưng khó thực hiện công việc một cách chính xác và bạn gặp vấn đề. Thêm phụ thuộc gốc.
  • IPC dựa trên socket với giao thức văn bản (XML, JSON, v.v.) - hoạt động OK và các định dạng phổ biến có thể được hỗ trợ ở cả hai đầu, nhưng thêm rất nhiều chi phí. Có thể là nỗi đau để duy trì ánh xạ lược đồ tùy chỉnh, v.v.
  • IPC dựa trên socket với giao thức nhị phân (ví dụ: bộ đệm giao thức của Google) - khá hiệu quả, cần nhiều công việc để giao thức tùy chỉnh hoạt động chính xác trên cả hai đầu
  • Giao tiếp qua một hệ thống thứ 3 (ví dụ như cơ sở dữ liệu, hàng đợi thông báo, hệ thống tập tin) - rất nhiều chi phí, có thể trở nên mong manh, giới thiệu sự phụ thuộc lớn vào hệ thống thứ 3.

Theo kinh nghiệm của tôi, nó thường là không đáng tích hợp một ngôn ngữ/nền tảng mới chỉ để có được một thư viện hoặc tính năng cụ thể. Lấy ví dụ về giao diện người dùng của bạn - bất kể Adobe Air trông đẹp như thế nào, tôi nghi ngờ nó rất đáng để cố gắng tích hợp nó với một ứng dụng C/C++ hiện có.

Ngay cả khi bạn làm cho nó hoạt động, nó sẽ làm phức tạp đáng kể việc bảo trì và phát triển ứng dụng của bạn trong tương lai. Các bản dựng trở nên phức tạp hơn. Bạn cần phải duy trì thêm thông tin liên lạc/"keo" mã. Bạn cần quản lý nhiều phụ thuộc hơn. Người dùng của bạn sẽ bị ảnh hưởng bởi nhiều sự cố cấu hình khác. Thử nghiệm trở nên khó khăn hơn. Nó trở nên khó khăn hơn để dạy một người mới về cách toàn bộ hệ thống hoạt động. Bạn cần duy trì kỹ năng của mình bằng nhiều ngôn ngữ/khuôn khổ hơn, v.v.

tôi khuyên bạn nên các chiến lược sau:

  1. Chọn một nền tảng chính
  2. Bất cứ khi nào bạn cần một thư viện hoặc tính năng mới, tìm kiếm một cái gì đó trên nền tảng chính của bạn đầu tiên. Hy vọng rằng (thường là?) Có cái gì đó tốt có sẵn - nhưng ngay cả khi không thì nó có thể là giá trị mã hóa một cái gì đó cho mình nếu yêu cầu là khá nhỏ.
  3. Chỉ khi có không có lựa chọn hợp lý trên nền tảng ban đầu, sau đó bạn có thể bắt đầu suy nghĩ về việc tích hợp một ngôn ngữ mới/nền tảng

Xét về nền tảng cơ bản, tôi muốn bình thường đề nghị một ngôn ngữ JVM như Java, Scala hoặc Clojure vì JVM được thiết kế rất tốt, mang lại hiệu năng tuyệt vời, có tính di động cao và có hệ sinh thái thư viện lớn nhất/gắn kết nhất (phần lớn là mã nguồn mở). Do đó, JVM có lẽ là lựa chọn "mục đích chung" tốt nhất trừ khi bạn có một số yêu cầu rất cụ thể mà không thể thực hiện được trên JVM, ví dụ:

  • Nếu bạn đang thực hiện rất nhiều chương trình nhúng/thời gian/hệ thống yêu cầu truy cập phần cứng, bạn có thể cần phải truy cập C/C++
  • Nếu bạn đang mã hóa hoàn toàn cho khách hàng dựa trên web, bạn có thể muốn sử dụng JavaScript (nếu bạn cũng đang viết mã ở phía máy chủ, bạn có thể xem xét các khung tạo mã JavaScript/thư viện có thể hoạt động trên JVM, ví dụ: Vaadin hoặc ClojureScript)
+0

Cả hai câu trả lời hay, nhưng câu trả lời này là eas tôi hiểu. Phần lớn công việc của tôi yêu cầu C/C++, tôi nghĩ rằng có thể an toàn khi đặt cược trên Qt làm "nền tảng" của tôi. – darasan

2

câu trả lời là khá nhiều phụ thuộc vào công nghệ bạn đang sử dụng và không có giải pháp viên đạn bạc cho việc này.

Nói chung, giải pháp này sẽ rơi vào một trong các loại sau:

  • Một số kỹ thuật thông tin liên lạc interprocess

  • Tích hợp được cung cấp bởi các ngôn ngữ/nền tảng riêng của mình

  • Cơ sở dữ liệu/số bộ nhớ chung (ngay cả các tệp :))

Ví dụ về đầu tiên: Ổ cắm/ống/bất kỳ hệ điều hành nào cho phép. CORBA - cho phép viết mã được phân phối bằng các ngôn ngữ khác nhau. Google protobuf - cho phép serialization/deserialization của các đối tượng dữ liệu và ngôn ngữ bất khả tri của nó

Thứ hai nó phụ thuộc vào ngôn ngữ/hệ sinh thái bạn đang sử dụng. Ví dụ về java:

  • JNI - Java Giao diện tự nhiên - cho phép thực thi mã (dll/so) bên ngoài JVM.
  • JCA - nếu bạn đang ở trong môi trường doanh nghiệp - bạn có thể viết tích hợp với các hệ thống cũ trong này.

Đối với ngôn ngữ được biên dịch thành mã nguồn gốc của nó ít phức tạp - bạn có thể viết và biên dịch một số mã, nói trong Pascal, và sau đó sử dụng DLL trong C.

Đôi khi chúng ta đang nói về Java có rất nhiều ngôn ngữ có cú pháp và trình biên dịch riêng, nhưng trình biên dịch của chúng biên dịch thành mã nhị phân java có thể chạy bên trong jvm. Vì vậy, nếu giải pháp của bạn dựa trên những ngôn ngữ này thì việc tích hợp sẽ dễ dàng hơn. Các ngôn ngữ như Scala, Groovy, Closure, Jython và những thứ khác đang rơi vào thể loại này.

Công nghệ cuối cùng nhưng không kém phần quan trọng nhất được đề cập là Dịch vụ web. Đây là một công cụ rất phổ biến để tích hợp hệ thống khác nhau, mặc dù nó được sử dụng nhiều hơn trong môi trường doanh nghiệp. Về cơ bản, nó trừu tượng hóa trên lớp ổ cắm cho phép gửi các đối tượng dữ liệu theo định dạng XML/JSON giữa các tiến trình/máy chủ. Cả XML và JSON là ngôn ngữ bất khả tri, do đó, nó không phải là một vấn đề để tạo ra một XML trong một chương trình được viết bằng C++ và sau đó tiêu thụ nó trong JAVA.

Hy vọng điều này sẽ giúp

Các vấn đề liên quan