2

私は現在、ユーザーが作業中のプロジェクトをハードディスクに保存できる「保存」メカニズムに取り組んでいます。出力は、あらゆる種類のデータを含む XML ファイルになります。
プロジェクト構造が変更されようとしており、新しい xml ファイルを作成する必要があります (新しい保存メソッドを作成します)。
ここで課題が発生します。保存するときに、作成するファイル形式 (バージョン 1 (古い) またはバージョン 2 (新しい)) をユーザーが選択できるようにしたいと考えています。
それを達成する方法はありますか?適切なデザインパターンはありますか?
備考: - 保存しているデータは無関係なブロックと見なすことができるため、実際には古いブロックを新しいブロックと簡単に交換できます。- 全体的な目標は、古いプロジェクトをロードするときに再び読み取れるようにすることです。(これはタグで実行できると思いますが、ロード時にタグに反応するだけですか?)

4

1 に答える 1

3

これは、 Strategyパターンの適切なアプリケーションのように思えます。

内部プロジェクト表現を XML に、またはその逆に変換するFileFormat2 つの仮想関数 と を使用して、抽象基本クラス (Strategy インターフェース) をprojectToXml作成します。xmlToProject

次に、2 つの実装サブクラスFileFormatNewFileFormatLegacy(これらは具体的な戦略です) を作成します。

保存関数はさらに FileFormat のインスタンスを必要とし、そのオブジェクトの対応するメソッドを呼び出してデータ変換を行います。ロード関数は、XML ツリーを調べて、それがどのバージョンであるかを示すものを調べることで、使用する戦略を選択できます。

また、別のファイル形式をサポートする必要がある場合は、FileFormat のサブクラスである新しいクラスを作成するだけです。

コメント交換後の追記

違いが非常に小さい多くのバージョンがあり、それでも Strategy パターンを使用したい場合は、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()
    );
}

注:実際のコードでは、もちろん、ストラテジー クラス名に "Old" や "New" よりもわかりやすいサフィックスを使用します。

于 2012-12-14T14:30:15.060 に答える