我不擅长OOP设计,但我需要向潜在雇主展示我的知识。 情况如下:
我有一个带有键值类型参数的文件,名为parameters.txt
。
我有一个map <string, CommonParamValue>
作为容器。我需要使用带参数的文件填充元素。密钥始终是std::string
参数,CommonParamValue
可以使用int
,double
,string
和标准函数调用来表示。为了实现这一点,CommonParamValue
是一个带有虚方法的基类。它有孩子 - StringParamValue
,DoubleParamValue
,CurTimeParamValue
。基类和每个子类都有一个方法virtual string GetValue()
,它返回内部数据的字符串表示形式; virtual void SetValue(string)
设置值。
问题是如何使用多态在运行时使用适当的数据填充容器map <string, CommonParamValue>
?现在我遇到了这样的情况:
parameters.txt
*user_name=Jane
*order_number=1325
current_date=
填写地图的例程
ifstream in(fileParamsPath);
if (! in)
{
cout << "Cannot open file with parameters, program is terminating." << endl;
cin.get();
exit(-1);
}
string key = "", value = "";
while(in)
{
getline(in, key, '=');
getline(in, value, '\n');
// put key and value into the container
// right here we need to analyze the data type and choose appropriate container.
// CommonParamValue *paramValue = new DoubleParamValue(); or
// CommonParamValue *paramValue = new CurTimeParamValue(); or
// CommonParamValue *paramValue = new StringParamValue();
paramValue->SetValue(value);
params.insert(make_pair(key, *paramValue)); // params is a map <string, CommonParamValue>
delete paramValue;
}
in.close();
有一个想法是在文件parameters.txt
中保留value-parameter的类型,并在填充map <string, CommonParamValue>
时分析它
parameters.txt
*user_name=Jane
string
*order_number=1325
int
current_date=
function
以这种方式修改例程以填充map <string, CommonParamValue>
:
string key = "", value = "", type = "";
while(in)
{
getline(in, key, '=');
getline(in, value, '\n');
getline(in, type, '\n');
in.get(); // got the dividing empty string
// put key and value into the container
// right here we need to analyze the data type and choose appropriate container.
if(type == "int")
{
CommonParamValue *paramValue = new IntParamValue();
}
else if(type == "function")
{
CommonParamValue *paramValue = new CurTimeParamValue();
}
else if(type == "string")
{
CommonParamValue *paramValue = new StringParamValue();
}
else
{
// error
exit(1);
}
paramValue->SetValue(value);
params.insert(make_pair(key, *paramValue)); // params is a map <string, CommonParamValue>
delete paramValue;
}
这是一个好的决定还是坏的?也许我的潜在雇主希望我以其他方式实施它,但我只有这个决定。对于初级C ++程序员来说,还有更好的吗?
答案 0 :(得分:2)
最适用的经典设计是factory method design。
CommonParamValue* createParamValue( const std::string &value );
createParamValue
方法负责创建相应的派生ParamValue
并将其作为CommonParamValue
返回。
你可以避免为&#34;类型&#34;通过使用值字符串在parameters.txt
内推断类型来导入createParamValue
。对于int
,double
和CurTime
,regular expression听起来最优雅。 Boost regex是一个示例库,允许您在c ++中执行此操作。但是,当然如果您正在寻找快速解决方案,那么编写自己的30行决策树对于这些简单的语法来说应该不是问题。
答案 1 :(得分:1)
客户端代码中的if语句看起来有点不合适。可以试试工厂级吗?
拥有基类IParamValue
IntParamValue : public IParamValue { }
static IParamValue * Create(string selection);
IParamValue * IParamValue::Create(string selection)
{
if (selection == "int") return new IntParamValue();
...
}
客户代码:
IParamValue* param = IParamValue::Create ("something");