データベースファイルを開く必要のあるアプリケーションで作業しています。このデータベースには2つの「バージョン」があります。1つはより一般的なデータストレージで、もう1つは「少ない」情報を含みます。そうは言っても、データベーステーブルの構造は異なるため、それぞれから「同じ」情報を取得するには、異なるクエリを発行する必要があります。
私の最初の考えは、クエリファクトリの抽象インターフェイスを作成することです。これには、クエリを返す純粋な仮想メソッドのみが含まれます。
class IQueryFactory
{
public:
virtual QString getNames() const = 0;
virtual QString getSurnames() const = 0;
// ...
};
また、データベースの両方の「バージョン」に対してこのインターフェースが実装されています。
class GeneralQueryFactory : public IQueryFactory
{
public:
QString getNames() const override
{
return "SELECT DISTINCT Name FROM People;";
}
QString getSurnames() const override
{
return "SELECT DISTINCT Surname FROM People;";
}
// ...
}
class SpecificQueryFactory : public IQueryFactory
{
public:
QString getNames() const override
{
return "SELECT DISTINCT FirstName FROM Employees;";
}
QString getSurnames() const override
{
return "SELECT DISTINCT LastName FROM Employees;";
}
// ...
}
プログラムの起動時にGeneralQueryFactory
とSpecificQueryFactory
のインスタンスを作成しています。データベースをロードするときに、データベース内のテーブルがあるかどうかを確認し、それに基づいて対応するクエリファクトリを保存しますマップ内のデータベース名を持つポインター:
GeneralQueryFactory generalFactory;
SpecificQueryFactory specificFactory;
// ...
if (...)
dbInfo.add(dbPath, &app.generalFactory);
else
dbInfo.add(dbPath, &app.specificFactory);
後で私は(別の関数で)次のようにクエリファクトリを使用します。
auto queryFct = dbInfo.getQueryFactory(dbPath);
QSqlQuery sqlQuery(queryFct->getNames());
sqlQuery.exec();
// ...
これが正しく行われたかどうか知りたい。この設計パターンの使用は、この問題に対して正しいですか?何を改善できますか?ありがとう。
あなたの「ファクトリー」はファクトリーではありません(少なくとも GoFブック が定義する方法ではありません)。しかし、これは単なる誤称だと思います。ここで示したのは 戦略パターン です。したがって、これらのクラスの名前を変更して、正しいGoF用語に一致させることを検討してください。
factory methodは、使用する戦略オブジェクトを決定するメソッドです。
IQueryStrategy &PickQueryStrategy()
{
if (...)
return &app.generalFactory;
else
return &app.specificFactory;
}
静的文字列の異なるセットを提供することが本当にここで必要な唯一のものである場合、戦略パターンはおそらく過度に設計されています。ディクショナリに保持されている2つの文字列リスト。データベースタイプは、このディクショナリのキー値として使用される列挙型であり、ボイラープレートコードが少なくて済み、おそらくより簡単です。次に、dbInfo
オブジェクトは、割り当てられたリストの1つを取得し、別の列挙型をインデックスとして使用して適切なクエリを選択します。
このリストを使用するコードは次のようになります。
auto queryList = dbInfo.getQueryList(dbPath);
QSqlQuery sqlQuery(queryList[QueryIndex::FirstName]);
ただし、より複雑な「実際の」コードがわからないため、戦略パターンの使用は完全に正当化される可能性があるため、必要なデータベースごとに異なる動作が発生する場合は、自分でこれを決定する必要があります。