2012-12-14 8 views
2

현재 사용자는 하드 디스크에서 작업중인 프로젝트를 저장할 수있는 "저장"메커니즘을 사용하고 있습니다. 출력은 모든 종류의 데이터를 포함하는 XML 파일입니다.
이제 프로젝트 구조가 바뀌려고하고 새로운 xml 파일을 작성해야합니다 (새 save 메소드 생성).
그래서 여기에 도전 과제가 있습니다. 저장할 때 사용자가 자신이 만들 파일 형식 (버전 1 (이전) 또는 버전 2 (신규))을 선택할 수 있기를 바랍니다.
누구나 지금 어떻게 할 수 있습니까? 주위에 적절한 디자인 패턴이 있습니까?
비고 :- 우리가 저장하는 데이터는 비 관련 블록으로 볼 수 있으므로 실제로는 이전 블록을 새 블록으로 쉽게 교체 할 수 있습니다. - 전체 목표는 이전 프로젝트를로드 할 때 다시 읽을 수 있어야한다는 것입니다. (태그로 할 수 있다고 가정하고, 로딩 할 때 태그에 반응해야만합니까?)"저장"을위한 디자인 패턴

+0

[전략] (http://en.wikipedia.org/wiki/Strategy_pattern)은 원하는 것처럼 들립니다. – StoryTeller

+1

[boost :: serialization] (http://www.boost.org/doc/libs/1_52_0/libs/serialization/doc/index.html) 개체를 XML 형식으로 저장하는 데 사용할 수 있습니다. – andre

+0

구글 프로토콜 버퍼와 페이 스북 드리프트가 해결하려고하는 것과 동일한 문제가있는 어떤 의미에서 ... –

답변

3

이것은 Strategy 패턴의 좋은 응용 프로그램처럼 들립니다.

두 개의 가상 함수 projectToXmlxmlToProject이있는 추상 기본 클래스 FileFormat (전략 인터페이스)을 만들면 내부 프로젝트 표현을 XML로 변환하거나 그 반대로 할 수 있습니다.

그런 다음 두 개의 구현 서브 클래스 FileFormatNewFileFormatLegacy을 작성합니다 (이것들은 구체적인 전략입니다).

저장 함수는 FileFormat의 인스턴스를 추가로 요구하고 해당 오브젝트의 해당 메소드를 호출하여 데이터 변환을 수행합니다. 로드 함수는 XML 트리에서 어떤 버전인지를 조사하여 사용할 전략을 선택할 수 있습니다.

다른 파일 형식을 지원해야하는 경우 FileFormat의 하위 클래스 인 새 클래스를 만들어야합니다.

부록 의견의 교환 후에는 아주 작은 차이 버전을 많이해야 할 것 당신은 여전히 ​​당신이 화일 형식을 여러의 합성을 할 수있는 전략 패턴을 사용하려면

전략 : CircleStragegy, RectangleStrategy, LineStrategy 등.이 경우 FileFormat의 다른 버전에 다른 클래스를 사용하지 않을 것입니다. 해당 버전에서 사용 된 Strategy 객체가 포함 된 FileFormat을 반환하는 각 버전에 대한 정적 팩토리 함수를 만듭니다.

FileFormat FileFormat::createVersion1_0() { 
    return new FileFormat(
     new LineStrategyOld(), 
     new CircleStrategyOld(), 
     new RectangleStragegyOld() 
    ); 
} 

FileFormat FileFormat::createVersion1_1() { 
    // the 1.1 version introduced the new way to save lines 
    return new FileFormat(   
     new LineStrategyNew(), 
     new CircleStrategyOld(), 
     new RectangleStragegyOld() 
    ); 
} 

FileFormat FileFormat::createVersion1_2() { 
    // 1.2 uses the new format to save circles 
    return new FileFormat(   
     new LineStrategyNew(), 
     new CircleStrategyNew(), 
     new RectangleStragegyOld() 
    ); 
} 

FileFormat FileFormat::createVersion1_3() { 
    // 1.3 uses a new format to save rectangles, but we realized that 
    // the new way to save lines wasn't that good after all, so we 
    // returned to the old way. 
    return new FileFormat(   
     new LineStrategyOld(), 
     new CircleStrategyNew(), 
     new RectangleStragegyNew() 
    ); 
} 

참고 : 물론 전략 클래스 이름을 "올드"과 "새로운"보다 더 많은 설명 접미사를 사용하는 것이 실제 코드에서.

+0

기본적으로 각 객체는 XML 데이터를 전달해야합니까? 의미는 내가 하나의 큰 방법을 모두 다른 사람들을 위해 공용 getters 및 setter를 사용하여 수집하지만 대신 "getAppropriateData()"메서드를 호출하고 개체 자체에서 데이터를 얻을 것이라고? 그리고이 방법을 사용하면 두 저장 버전 사이의 가장 작은 변경 사항에도 새로운 구체적인 전략이 필요합니다.이 구체적인 전략은 마지막 변경 사항과 동일한 기능을 모두 호출합니다. 단 하나의 작은 변경 만 제외하고는? – Donny

+0

중복 코드는 항상 피해야합니다. 두 가지 전략이 매우 유사하고 약간의 차이 만 다를 때 둘 중 하나가 다른 것을 상속 할 수 있거나 코드의 대부분을 기본 클래스의 공통된 사적 기능으로 옮길 수 있으며 각 코드에서 실제로 다른 부분 만 수행 할 수 있습니다 수업. – Philipp

+0

전략에 따라 저장해야하는 데이터를 수집하는 방법 : 이에 대한 권장 사항을 제공하기 위해 데이터가 어떻게 구성되어 있는지 알아야합니다. 저장해야하는 모든 것에 게터를 사용하여 프로젝트 클래스의 세부 사항을 너무 많이 노출시키지 않으려면 Visitor 패턴을 사용하여 데이터를 수집 할 수 있습니다. http://en.wikipedia.org/wiki/Visitor_pattern – Philipp