この種のことを行う多くのコードを含む大規模なコードベースがあります。
bool DoSomething(CString Value)
{
if(Value == "bad")
{
AfxMessageBox("description of error");
return false;
}
return true;
}
またはこれだけでも:
bool DoSomething(CString Value)
{
if(Value == "bad")
{
return false;
}
return true;
}
さまざまな代替案を検討しました。
- 例外 - 基本的に、ここで説明されているように、短所を売りにしています: http://www.codeproject.com/Articles/38449/C-Exceptions-Pros-and-Cons
- エラーテキストが入力された追加の文字列参照パラメーターを渡す - ただし、呼び出しの前にエラー文字列を事前にインスタンス化する必要があり、パラメーターリストにバルクを追加します
- 「last_error」メンバー変数の設定 - これは、ここで表現されている欠点に苦しんでいるようです (imo): GetLastError() は設計パターンのようなものですか? いい仕組みですか?
- 他の関数を使用してエラーの説明にマップできる列挙型 (など) を返す - しかし、これは小さな関数やオブジェクトには「重く」感じられ、エラーが発生した場所とエラーが発生した場所の間にスペースが作成されます。メッセージは維持されます (多言語環境では、テキストの集中化を歓迎すると思いますが)。
そこで、次のような一連のクラスを作成できないかと考えました。
class CResult
{
protected:
CResult()
{
// Don't have to initialize because the derived class will do it
}
public:
operator bool() { return m_Result; };
bool m_Result;
CString m_Message;
};
class CSuccess : public CResult
{
public:
CSuccess()
{
m_Result = true;
}
};
class CFailure : public CResult
{
public:
CFailure(const CString & Message)
{
m_Result = false;
m_Message = Message;
}
};
次に、上記のコードは次のようになります。
CResult DoSomething(CString Value)
{
if(Value == "bad")
{
return CFailure("description of error");
}
return CSuccess();
}
私が気に入っているところ:
- コードはまだ読み取り可能で、エラー メッセージはエラー状態の近くに維持されます
- プログラマーは、エラー状態で実際にエラー文字列を提供することを少し強制されます (はい、空白を提供することもできますが、それはもっとひどい間違いのように思えます)。
- 呼び出し元は、関数呼び出しの前に特別な変数を作成する必要がなく、関数の結果を bool のように扱うことができます。または、エラーが無視されない場合は、簡単に説明を取得できます。
- 次のプログラマーは、関数定義を見るだけで、どのエラー モデルが使用されているかがわかります。
私が見る主な欠点は、オブジェクトと文字列とブールがすべてインスタンス化されるという点で、成功時のオーバーヘッドが高くなることです - しかし、私たちのアプリでは多くの場合、問題のコードは検証などのパフォーマンスに敏感ではありませんユーザー入力など
私は他の大きな欠点を見逃していますか?さらに良い解決策はありますか?