0

クラスの作成に使用されるファクトリ メソッド パターンがあり、実際の作成に進む前に入力パラメーターを検証したいと考えています。ここで扱っているのは A と B の 2 つのクラスで、それぞれに独自の検証があります。作成テンプレート関数で既にクラス タイプ (A または B) を渡しているので、そのタイプを直接使用して、どの検証を使用する必要があるかを伝えたいと思います。テンプレート関数の特殊化またはダミー入力パラメーターを使用してそれを行うことを検討していますが、それぞれに長所/短所があります。どちらかがより合理的に見えるか、または他のオプションもある場合はお知らせください。ありがとう!

ああ、私は検証を A または B の静的メソッドにすることを検討しましたが、レガシー コードを扱っており、そのようなものを移動するのはあまり簡単ではないため、見栄えがよくありませんでした。ただし、完全を期すために、これを以下のオプションとして示しました。

テンプレート機能の特化:

長所: 検証を選択するために、FactoryCreateClass メソッドに渡された型を直接使用できる

短所: 特殊化しかないため、テンプレート メソッドは活用されていません。

template <typename T>
void FactoryCreateClass (int, double)
(
    bool bSuccess = ValidateBlock<T>(int, double);

    if (bSuccess)
        T* = T::CreateInstance();           
)

template <typename T>
bool ValidateBlock (int double);    // don't need an implementation here since 
                                    // all specialization require different validation

template <>
bool ValidateBlock<A> (int, double)
{
    //do validation before creating A
}

template <>
bool ValidateBlock<B> (int, double)
{
    //do validation before creating B
}

ダミー変数:

長所: 検証を選択するために、FactoryCreateClass メソッドに渡された型を直接使用できる

短所:未使用のダミー変数

template <typename T>
void FactoryCreateClass (int, double)
(
    bool bSuccess = ValidateBlock(T /*dummy*/, int, double);

    if (bSuccess)
        T* = T::CreateInstance();           
)

bool ValidateBlock (A/*dummy*/, int, double)
{
    //do validation before creating A
}

bool ValidateBlock (B/*dummy*/, int, double)
{
    //do validation before creating B
}   

静的クラス メソッド:

長所: 検証を選択するために、FactoryCreateClass メソッドに渡された型を直接使用できる

短所: レガシー コードでこの種の変更を行うのは難しい

template <typename T>
void FactoryCreateClass (int, double)
(
    bool bSuccess = T::ValidateBlock(int, double);

    if (bSuccess)
        T* = T::CreateInstance();           
)

static bool A::ValidateBlock (int, double)
{
    //do validation before creating A
}

static bool B::ValidateBlock (int, double)
{
    //do validation before creating B
}
4

2 に答える 2

1

ここでの最も適切な設計は、CreateInstanceメソッド内で検証を行うことです。これは、タスク(引数の検証とインスタンスの作成)が強力に結合されており、これらを1か所にまとめた方がはるかに読みやすいためです。

ただし、場合によっては、CreateInstanceメソッドのコードを変更することはできません。そうですね、関数テンプレートとダミー変数のどちらを使用しても大きな違いはありません。ただし、後者もう少し明確で、読みやすくなっています。

ちなみに、参照されていない変数は実際には大きな問題ではありません。それを抑制することができます 。単一の警告エラーを無効にするを参照してください。ページで検索しUNREFERENCED_PARAMETERてください。

于 2013-02-24T16:24:40.180 に答える
1

3 番目の選択肢を忘れています: 特性の使用です。

template <typename> struct Trait;

template <>
struct Trait<A> {
    static bool Validate(int, double);
};

template <>
struct Trait<B> {
    static bool Validate(int, double);
};

その後:

template <typename T>
void FactoryCreateClass(int i, double d) {
    bool const success = Trait<T>::Validate(i, d);
    // ...
}

しかしもちろん、本当の問題は、なぜ検証をCreateInstance直接行わないのかということです。

于 2013-02-24T13:58:12.503 に答える