다른 버전의 소프트웨어간에 파일의 이전 버전과의 호환성을 허용하는 좋은 디자인은 무엇입니까?


14

서로 다른 버전의 소프트웨어간에 파일 형식의 이전 버전과의 호환성을 허용하는 좋은 디자인은 무엇입니까?

예를 들어, Microsoft가 열린 모든 docx 파일에 워드 2007, 2010 및 2013 등을 어떻게 제공합니까? 그러나 다른 버전의 데이터는 더 많거나 적은 데이터를 저장하고 데이터를 약간 다른 방식으로 동일한 파일 형식으로 저장할 수 있습니다. 한 버전으로 저장된 파일을 다른 버전에서 열 수 있지만 파일의 특정 요소를 이전 버전에서 사용하지 못할 수 있습니까?

정말 확실한 방법은

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

그러나 그것은 엄청나게 모 놀리 식처럼 보이고 확장 성이 높지 않으며 많은 복사 / 붙여 넣은 코드로 이어질 수 있습니다.

그래서 헤더와 같이 파일에 있어야하는 불변의 구조와 직렬화 / 역 직렬화에 사용할 수 있어야하는 메소드와 다중 상속을 정의하는 모든 버전에 기본 인터페이스를 사용하려고 생각했습니다. 인터페이스를 구현하는 새 버전의 클래스는 이전 버전을 상속하며 파일이 동일하기 때문에 변경된 내용 만 대체합니다.

XML의 사용 여부를 이미 결정했으며 초기 스키마는 이미 결정되었으므로 파일 구조에 대해서는 실제로 신경 쓰지 않았습니다. 그러나 앞으로도 변경이있을 것이므로 이러한 변경 사항을 쉽게 수용 할 수있는 방식으로 코드를 디자인 할 수 있기를 바랍니다.


6
소스가 이전 버전에서 왔기 때문에 누락 된 정보뿐만 아니라 소스가 최신 버전 에서 왔기 때문에 예상하지 않은 정보도 무시하도록 파일 형식을 설계해야합니다 . 처음부터 시작하는 경우 호환성 도 함께 수행하십시오. 추가 노력이 거의 들지 않으며 소프트웨어의 유용성이 두 배가됩니다.
Kilian Foth

열려있는 상태에서 처리중인 파일 버전을 항상 미리 알고 있습니까 (예 : 헤더에서)? 또한 다른 요청을하려면 손상되거나 악성 파일이 있는지 확인한 후 문제가 발생하지 않도록하십시오. 시스템 관리자가 감사합니다 :).
cxw

1
예, 버전 번호는 항상 파일 헤더에 있으며 헤더 형식은 변경되지 않습니다. 우리는 마이너 소프트웨어 버전 사이에 생성 된 파일이 호환 가능해야한다는 아이디어를 가지고 있습니다. 예를 들어, v1.1에서 생성 된 파일은 v1.2에서 열 수 있으며 그 반대도 마찬가지입니다. 1.2의 일부 기능은 1.1에서 누락되었지만 주요 수정 버전이 있습니다. v2로 작성된 내용은 v1에서 열리지 않지만 v1로 작성된 내용은 v2에서 열립니다.
JJBurges

그리고 손상에 관해서는 파일에 DSL이 포함되어 있으며 파일을 열고 닫는 프로그램은 사용자 정의 사내 IDE / 컴파일러입니다. 이것들은 프로덕션 환경 근처에 있지 않으므로 관리자는 걱정할 필요가 없습니다.
JJBurges

답변:


10

PNG 파일 형식과 버전 호환성을 처리하는 방법을 살펴볼 수 있습니다. 모든 블록에는 어떤 종류의 블록인지 설명하는 ID가 있으며 해당 ID를 이해할 수없는 경우 어떻게해야하는지 소프트웨어에 알려주는 플래그가 있습니다. 예를 들어 "이 블록을 이해하지 못하면 파일을 읽을 수 없습니다"또는 "파일을 읽을 수는 있지만 수정할 수는 없습니다"또는 "파일을 수정할 수는 있지만이 블록을 삭제해야합니다"와 같습니다. 이전 버전과의 호환성을 위해 소프트웨어는 예상 데이터가없는 상황을 처리하기 만하면됩니다.


좋은 생각이야! PNG 형식은 버전이 아닌 기능에 의존합니다. 그러나 기본 형식은 절대 변하지 않아야합니다. (즉, 기능을 정의하는 헤더)
Florian Margaine

그 흥미 롭군요. 현재 파일 사양을 읽고 있습니다. 나는 비판적 및 부수적 인 덩어리에 대한 아이디어를 좋아하며 이것을 시도해 볼 수도 있습니다.
JJBurgess

3

이를 수행하는 방법은 파일 처리를위한 기본 기능과 기본 클래스 및 인터페이스를 사용하는 것입니다. 그런 다음 기본 클래스에서 확장 된 각 버전의 클래스를 사용하여 모든 버전 별 사례를 처리하십시오. 버전 별 구현 만있는 경우 기본 추상 클래스에서 변경할 수있는 함수가 가상 일 수 있습니다. 파일을 처리하기 위해 클래스가 필요한 경우 파일 처리 인터페이스의 버전 별 구현을 가져 오는 팩토리를 사용하십시오.


이것에 대한 유일한 문제는 각 후속 개정에 대해 버전 특정 구현을 복제한다는 것입니다. ReadNames (), ReadAges () 및 ReadAddresses ()의 세 가지 기본 클래스 메소드가 있고 클래스의 V2에서 ReadAges ()를 변경한다고 가정합니다. V3에서 ReadNames ()를 변경하기로 결정한 경우 모든 버전 별 클래스가 기본 클래스에서 상속되는 경우 V2 변경 사항이 손실되거나 V2의 변경 사항을 복사 / 붙여 넣기해야합니다. V3 구현으로도.
JJBurges

1
판독의 구현은이 버전의 연령을 읽는 방법에 대한 실제 구현을 보유하는 다른 클래스를 호출 할 수 있습니다. 수업은 실제 프로그래밍보다 더 많은 인터페이스 / 공장 구성이 될 것입니다.
peer

2

XML 로이 작업을 수행했으며 잘 작동합니다.

문서의 어떤 요소도 속성과 하위 요소를 갖도록 허용합니다 (순서가 중요하지 않은 경우 순서대로). 프로그램의 첫 번째 버전부터 시작-문서를 읽을 때 현재 버전에서 모르는 속성 및 하위 요소를 무시하십시오.

나중에 새 버전의 프로그램에 새 기능을 추가 할 때 속성 또는 하위 요소를 추가하십시오. 이전 버전에서는 무시됩니다. 새 버전은 속성 또는 하위 요소의 누름을 확인하고 처리해야합니다.

예를 들어 텍스트가있는 항목이 있습니다.

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

그리고 최신 버전에서는 항목에 색상을 추가하여 속성을 추가하려고합니다 color.

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

이전 버전은 color문서를 열 때 속성을 무시 합니다. 새로운 버전은 color속성의 누르기를 확인하고 존재하지 않는 경우 기본 색상을 할당합니다.

이 간단한 솔루션을 사용하면 이전 버전과 이전 버전의 호환성을 모두 유지할 수 있습니다.


이것을 "간단한"옵션으로 사용하는 약간의 문제는 문서를 저장할 때 모든 예상치 못한 속성을 제거하거나 변경하지 않은 상태로 유지한다는 것입니다. 다른 답변에서 언급했듯이 더 나은 솔루션은 적어도 일부 버전에서 속성을 삭제하거나 유지 해야하는지 또는 문서를 이해하지 못하는 버전에 대해 읽기 전용으로 만들어야하는지 여부에 대해 일부 버전에 관계없이 결정합니다.
Mark Hurd

@Mark Hudr : 그렇습니다. 나는 이전 버전과의 호환성이 있어야하고 앞으로 호환성이 보너스라고 가정합니다. 누군가 이전 버전의 응용 프로그램에서 새 문서를 열면 문서를 저장할 때 이전 응용 프로그램에서 아직 보이지 않는 것을 잃어버린 것에 놀라지 않아야합니다. 추가 논리가 나에게 너무 엔지니어링 된 것 같습니다.
user3123061
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.