私は現在、ユーザーが作業中のプロジェクトをハードディスクに保存できる「保存」メカニズムに取り組んでいます。出力は、あらゆる種類のデータを含む XML ファイルになります。
プロジェクト構造が変更されようとしており、新しい xml ファイルを作成する必要があります (新しい保存メソッドを作成します)。
ここで課題が発生します。保存するときに、作成するファイル形式 (バージョン 1 (古い) またはバージョン 2 (新しい)) をユーザーが選択できるようにしたいと考えています。
それを達成する方法はありますか?適切なデザインパターンはありますか?
備考: - 保存しているデータは無関係なブロックと見なすことができるため、実際には古いブロックを新しいブロックと簡単に交換できます。- 全体的な目標は、古いプロジェクトをロードするときに再び読み取れるようにすることです。(これはタグで実行できると思いますが、ロード時にタグに反応するだけですか?)
1 に答える
これは、 Strategyパターンの適切なアプリケーションのように思えます。
内部プロジェクト表現を XML に、またはその逆に変換するFileFormat
2 つの仮想関数 と を使用して、抽象基本クラス (Strategy インターフェース) をprojectToXml
作成します。xmlToProject
次に、2 つの実装サブクラスFileFormatNew
とFileFormatLegacy
(これらは具体的な戦略です) を作成します。
保存関数はさらに 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" よりもわかりやすいサフィックスを使用します。