Designfrage: Konvertierungen mit Einschränkung
-
Guten Abend,
ich habe folgendes Problem: Ich will ein Konsolen-Tool schreiben das verschiedene Dateiformate ineinander konvertieren kann (von einer Quelldatei in eine Zieldatei). Jedes Dateien-Paar kann dabei unterschiedliche Optionen haben (die die Konvertierung beeinflussen) und es sind auch nicht alle Konvertierungsrichtungen erlaubt. Beispiel:
Sagen wir es gibt 3 Datei-Formate: .A, .B und .C und der Konverter soll folgende Konvertierungen erlauben:
.A -> .B (Optionen --a1 und --a2)
.A -> .C (Optionen --a1 und --a2 --a3)
.B -> .A (Option --b1)
Ich kann also z.B. eine .A Datei in eine .B Datei konvertieren (und umgekehrt) oder eine .A Datei in eine .C Datei konvertieren. .B nach .C geht hingegen NICHT.
Wenn ich von .A nach .B konvertiere, kann der User noch die Optionen --a1 und --a2 setzen. Von .A nach .C kann er Optionen --a1, --a2 und --a3 wählen.Ich frage mich gerade, wie man das Designen könnte. Mein jetziges Design sieht grob so aus:
class Database { public: Database(const string& filename); virtual void createFromFile() = 0; virtual void createFromDataBase(const Database& db); virtual void save() = 0; }; class ADatabase : public Database { // Handelt .A Dateien public: ADatabase (const string& filename); virtual void createFromFile() { ... } // Liest .A Datei ein virtual void createFromDataBase(const Database& db) { } // Erzeugt .A Datei aus einem anderen Format virtual void save() { } // Speichert .A Datei }; // ... weitere Database Subklassen für jedes Format class Converter { // Ein Converter hat eine Quell und Ziel-Datenbasis und eine Config (--a1, --a2 etc.) Database* sourceDB; Database* targetDB; Config config; public: Converter(const string& sourceFile, const string& targetFile) { sourceDB = ... (Typ Abhängig vom file. Für ein "foo.A" wird z.B. eine ADatabase erzeugt) targetDB = ... } void convert(const string& sourceFile, const string& targetFile) { sourceDB->createFromFile(); targetDB->createFromDataBase(sourceDB); targetDB->save(); } };Die Logik: Ich erstelle für jedes Format eine Subklasse von Database und die Konvertierung läuft dann so ab: sourceDB liest Datei, targetDB erhält die fertige source database und erzeugt sich quasi aus dieser (das ist die Konvertierung).
Was mir an dem Design nicht gefällt:
1. Die verschiedenen Datenbasen können NICHT alle alles. Aus obigem Beispiel: Eine CDatabase kann z.B. NICHT zum Laden einer Datei benutzt werden und eine BDatabase könnte man NICHT benutzen um eine .C Datei zu schreiben. In meinem Design sieht man diese Einschränkungen nicht.
2. Die verschiedenen Konvertierungen haben ganz unterschiedliche Optionen und auch das sieht man in meinem Design nicht.Hat jemand Ideen, wie ich das verbessern könnte? Oder ganz anders machen kann?
-
class Database { /* ... */ }; class A { Database data; public: void read_from_file(/*...*/ ) {/*...*/} void write_as_B(Optionstype options , /*...*/){/*...*/} void write_as_C(Optionstype options , /*...*/){/*...*/} }; class B { Database data; public: void read_from_file(/*...*/ ) {/*...*/} void write_as_A(Optionstype options , /*...*/){/*...*/} };
-
Wenn möglich:
class Database { ... }; void write_as_A( const Database& db ); void write_as_B( const Database& db ); void write_as_C( const Database& db );
-
Hi könntest du mir mal deinen Source code als pn zuschicken habe ein ähnliches Problem