オブジェクト指向のアプローチを使用して、関数/メソッドが受け取るパラメーターのセットを検証するソリューションを考えていました。たとえば、次のスニペットでは、パラメーターは使用前に「手動で」チェックされます。
InstallData::InstallData(std::string appPath, std::string appName,
std::string errMsg) {
if(appPath.empty()) {
#ifndef NDEBUG
std::cout << "Path not specified" << std::endl;
#endif
}
if(appName.empty()) {
#ifndef NDEBUG
std::cout << "Application name not specified" << std::endl;
std::cout << "Defaulting to AppName" << std::endl;
this->appName = "AppName";
#endif
}
if(errMsg.empty()) {
#ifndef NDEBUG
std::cout << "Error message not specified" << std::endl;
std::cout << "Defaulting to Error" << std::endl;
this->errMsg = "Error";
#endif
}
// ... further initialization beyond this point ...
}
パラメータの数が増えると、検証コードのサイズも大きくなります。パラメータ(文字列とポインタ)が空かnullかをチェックする基本的なアプローチを考えました(目的は、機能を提供するコードをより読みやすくすることです)。
class Validator {
public:
bool validateStrs(std::vector<std::string> strings, std::vector<std::string> messages, bool quiet);
bool validateStr(std::string str, std::string message, bool quiet);
bool validatePtrs(std::vector<void*> ptrs, std::vector<std::string> messages, bool quiet);
bool validatePtr(void* ptr, std::string message, bool quiet);
};
検証メソッドの validateStrs と validatePtrs は、最初の配列の各要素が空か null かをチェックし、quiet フラグが設定されていません。
私の実装では、これは次のようになります。
InstallData::InstallData(std::string appPath, std::string appName,
std::string errMsg, std::string errTitle) {
// Initialize string container
std::vector<std::string> strings;
strings.push_back(appPath);
strings.push_back(appName);
strings.push_back(errMsg);
strings.push_back(errTitle);
// Initialize name container
std::vector<std::string> names;
names.push_back("ApplicationPath");
names.push_back("ApplicationName");
names.push_back("ErrorMessage");
names.push_back("ErrorTitle");
boost::shared_ptr<Validator> valid(new Validator());
bool result = true;
#ifndef NDEBUG
result = valid->validateStrs(strings, names, false);
#else
result = valid->validateStrs(strings, names, true);
#endif
if(result){
this->appPath = appPath;
this->appName = appName;
this->errMsg = errMsg;
this->errTitle = errTitle;
} else {
std::exit(0);
}
}
メッセージは別のファイルに配置することもできるため、メソッド本体がよりきれいになります。
数値範囲チェッカーも同様に実装できます。ただし、このアプローチでは、パラメーター間の依存関係は考慮されません。
おそらくテンプレートを使用して、パラメーター検証メカニズムを実装するより洗練されたソリューションはありますか?