Một thiết kế tốt để cho phép khả năng tương thích ngược của các tệp giữa các phiên bản phần mềm khác nhau là gì?


13

Một thiết kế tốt để cho phép khả năng tương thích ngược của một loại tệp giữa các phiên bản phần mềm khác nhau là gì?

Chẳng hạn, làm thế nào microsoft có được word 2007, 2010 và 2013, v.v ... cho tất cả các tệp docx đang mở, nhưng các phiên bản khác nhau có thể lưu nhiều hơn / ít dữ liệu hơn và lưu dữ liệu theo các cách hơi khác nhau, tất cả vào cùng một loại tệp và a tập tin được lưu trong một phiên bản có thể được mở trong một phiên bản khác, nhưng một số yếu tố nhất định của tập tin có thể không có sẵn trong các phiên bản cũ hơn?

Ý tôi là, cách thực sự rõ ràng để làm điều đó là có một cái gì đó như

private string openfile(string filename)
{
    File.Open(filename)

    ... some logic that gets a header from the file that will never change

    switch (fileversion)
        case 2007:
            .....
        case 2010
            .....
        case 2013
            .....
}

nhưng điều đó dường như vô cùng nguyên khối, không thể mở rộng và có khả năng dẫn đến rất nhiều mã sao chép / dán.

Vì vậy, tôi đã nghĩ đến việc sử dụng giao diện cơ sở cho tất cả các phiên bản xác định cấu trúc bất biến, chẳng hạn như tiêu đề, cần phải có trong tệp và các phương thức cần có sẵn để tuần tự hóa / giải tuần tự hóa, sau đó nhiều kế thừa để mỗi kế thừa Lớp của phiên bản mới thực hiện giao diện kế thừa phiên bản cũ và chỉ ghi đè lên những thứ đã thay đổi, vì phần lớn tệp sẽ giống nhau.

Tôi không thực sự bận tâm về cấu trúc của tệp, vì nó đã quyết định rằng chúng tôi sẽ sử dụng XML và lược đồ ban đầu, nói chung, đã được quyết định. Tuy nhiên, không có nghi ngờ gì về những thay đổi trong tương lai và tôi chỉ muốn có thể thiết kế mã theo cách giúp dễ dàng điều chỉnh những thay đổi này.


6
Bạn nên thiết kế định dạng tệp để không chỉ bỏ qua thông tin bị thiếu vì nguồn là từ phiên bản cũ hơn, mà còn là thông tin mà nó không mong đợi vì nguồn đó là từ phiên bản mới hơn . Nếu bạn đang bắt đầu từ đầu, xin vui lòng cũng làm tương thích về phía trước . Nó gần như không có thêm nỗ lực và tăng gấp đôi tính hữu ích của phần mềm của bạn.
Kilian Foth

Khi mở, bạn sẽ luôn biết trước (ví dụ: từ tiêu đề) bạn đang xử lý phiên bản tệp nào? Ngoài ra, để thực hiện một yêu cầu khác, vui lòng kiểm tra các tệp bị hỏng hoặc độc hại và đừng để chúng gây ra sự cố. Sysadins của bạn sẽ cảm ơn bạn :).
cxw

1
Có, số phiên bản sẽ luôn ở trong tiêu đề tệp và định dạng tiêu đề sẽ không bao giờ thay đổi. Chúng tôi sẽ nghĩ rằng các tệp được tạo giữa các phiên bản phần mềm nhỏ phải tương thích, nghĩa là một tệp được tạo trong v1.1 có thể được mở trong v1.2 và ngược lại, mặc dù một số chức năng từ 1.2 có thể bị thiếu trong 1.1 nhưng các phiên bản chính sẽ phá vỡ tính tương thích về phía trước, vì vậy những thứ được viết trong v2 sẽ không mở trong v1, nhưng những thứ được viết trong v1 sẽ mở ra trong v2.
JJBurgess

Và đối với điều tham nhũng, các tệp chứa DSL và chương trình mở / đóng chúng là một trình biên dịch IDE / trình biên dịch tùy chỉnh. Chúng sẽ không xuất hiện ở bất cứ đâu gần môi trường sản xuất, vì vậy, quản trị viên không cần phải lo lắng.
JJBurgess

Câu trả lời:


10

Bạn có thể xem định dạng tệp PNG và cách xử lý tương thích phiên bản. Mỗi khối có một id mô tả loại khối đó là gì và nó có một số cờ cho phần mềm biết phải làm gì nếu không thể hiểu id đó. Ví dụ: "bạn không thể đọc tệp nếu bạn không hiểu khối này" hoặc "bạn có thể đọc tệp nhưng không sửa đổi tệp" hoặc "bạn có thể sửa đổi tệp nhưng bạn phải xóa khối này". Để tương thích ngược, phần mềm của bạn chỉ cần xử lý tình huống khi không có dữ liệu dự kiến.


Ý tưởng tuyệt vời! Định dạng PNG dựa trên các tính năng chứ không phải trên các phiên bản. Tuy nhiên, điều đó có nghĩa là định dạng cơ bản không bao giờ thay đổi. (tức là tiêu đề xác định tính năng.)
Florian Margaine

Nó thật thú vị. Tôi đang đọc thông số kỹ thuật tập tin tại thời điểm này. Tôi thích ý tưởng về các phần quan trọng và phụ trợ, và có thể thử và thực hiện điều này.
JJBurgess

3

Một cách để làm điều này có thể là bằng cách sử dụng một lớp cơ sở và giao diện với các chức năng cơ bản để xử lý tệp của bạn. Sau đó sử dụng các lớp cho mỗi phiên bản mở rộng từ lớp cơ sở để xử lý tất cả các trường hợp cụ thể của phiên bản. Các hàm có thể thay đổi có thể là ảo trong lớp trừu tượng cơ sở của bạn nếu chỉ có các triển khai cụ thể của phiên bản. Khi bạn cần một lớp để xử lý tệp, hãy sử dụng một nhà máy có phiên bản triển khai cụ thể của giao diện xử lý tệp.


Vấn đề duy nhất của tôi với điều này là cuối cùng bạn sẽ sao chép triển khai cụ thể phiên bản cho mỗi lần sửa đổi tiếp theo. Hãy nói rằng bạn có ba phương thức lớp cơ sở: ReadNames (), ReadAges () và ReadAddresses () và trong V2 của lớp, bạn thực hiện thay đổi thành ReadAges (). Nếu ở V3, sau đó bạn quyết định thay đổi thành ReadNames (), nếu tất cả các lớp cụ thể phiên bản của bạn được kế thừa từ cơ sở, bạn sẽ mất các thay đổi V2 hoặc bạn cần sao chép / dán các thay đổi từ V2 vào việc thực hiện V3 là tốt.
JJBurgess

1
Việc thực hiện các bài đọc có thể gọi một lớp khác tổ chức triển khai thực tế về cách đọc độ tuổi cho phiên bản này. Làm cho lớp của bạn sẽ có nhiều cấu hình của giao diện / nhà máy hơn là lập trình thực tế.
ngang hàng

2

Tôi đã làm điều này với XML và nó hoạt động tốt:

Đơn giản chỉ cần cho phép bất kỳ yếu tố nào trong tài liệu của bạn, có bất kỳ thuộc tính và bất kỳ phần phụ nào (và khi thứ tự không quan trọng - theo bất kỳ thứ tự nào). Bắt đầu từ phiên bản đầu tiên của chương trình - khi đọc tài liệu, bỏ qua các thuộc tính và thành phần phụ mà bạn không biết trong phiên bản hiện tại.

Trong tương lai khi bạn thêm tính năng mới vào phiên bản mới của chương trình, sau đó thêm thuộc tính hoặc thành phần phụ. Các phiên bản cũ hơn sẽ bỏ qua nó. Phiên bản mới nên kiểm tra áp lực của thuộc tính hoặc thành phần phụ và xử lý với nó.

Ví dụ: bạn có một số mục có văn bản:

<item text="Hello, world!"/>

Và trong phiên bản mới hơn, bạn muốn thêm màu vào mục để thêm thuộc tính color:

<item text="Hello, world!" color="008000"/>

Phiên bản cũ hơn sẽ đơn giản bỏ qua colorthuộc tính khi mở tài liệu. Các phiên bản mới kiểm tra mức độ áp lực của colorthuộc tính và nếu không tồn tại sẽ gán màu mặc định.

Với giải pháp đơn giản này, bạn sẽ có cả khả năng tương thích ngược và tiến.


Vấn đề nhỏ với tùy chọn "đơn giản" này là bạn sẽ loại bỏ tất cả các thuộc tính không mong muốn (hoặc giữ chúng không thay đổi) khi lưu tài liệu. Như đã đề cập trong các câu trả lời khác, một giải pháp tốt hơn ít nhất xác định theo một cách bất khả tri nào đó về việc liệu một thuộc tính có nên bị loại bỏ, giữ hoặc làm cho tài liệu trở thành chỉ đọc cho các phiên bản không hiểu nó hay không.
Đánh dấu

@Mark Hudr: Vâng, tôi âm thầm cho rằng phải có khả năng tương thích ngược và tương thích về phía trước là tiền thưởng. Khi ai đó mở tài liệu mới trong phiên bản cũ của ứng dụng, họ không nên ngạc nhiên rằng khi họ lưu nó, họ đã mất một thứ không thể nhìn thấy trong ứng dụng cũ. Logic bổ sung có vẻ áp đảo đối với tôi.
dùng3123061
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.