假设我想制作一个文件解析器,它使用类似策略的模式来允许使用不同的特定解析器,这些解析器将完成所有艰苦的工作,然后返回它们之间可能有所不同的结果。
例如,文件的每一行都包含 A、B、C、D 和 E,而我只想获取 A、C 和 E,因此我创建了一个特定的解析器来仅提取它们。
我还应该注意,我正在处理 NMEA 格式,每个解析器将处理文件中的不同语句(行)。
class FileParser
{
std::string file_path;
public:
FileParser(std::string file_path, ??? parser);
void parseFile() {
// ...
// for each line:
parser.parseStatement(line);
// end for
// ...
}
??? getResults() {
return parser.getResults();
}
};
class Parser
{
public:
virtual void parseLine(std::string line);
??? getResults();
}
class SpecificParser : public Parser
{
void parseLine(std::string line);
SpecificFormat getResults();
}
我的问题是 - 如何正确编写这样的代码? 我的第一个想法是模板,但我还不知道如何使用它们,所以第二个想法是:
FileParser otherFunction() {
ExampleParser ep();
FileParser fp("example.txt", &ep);
return fp;
}
void function() {
FileParser fp = otherFunction(); // countains reference to deleted instance of ExampleParser
}
...但它也有问题(我故意展示了一个边缘情况)。
构建该代码的正确方法是什么?
示例用例(如下要求)
auto parser1 = FileParser<SpecificParserType1>(file_name);
parser1.parseFile();
auto parser1.getResults(); // returns instance of specific type 1, e.g. std::vector<Type1>
auto parser2 = FileParser<SpecificParserType2>(file_name);
parser2.parseFile();
auto parser2.getResults(); // returns instance of specific type 2, e.g. std::vector<Type2>
主要目标是能够采用不同的策略从文件中获取数据。
最佳答案
从我的角度来看,您在这里使用策略模式的想法是错误的,因为:
您想要创建一个始终具有几乎相同签名的类层次结构,这已经显示了您的问题:存在设计问题,因为您的具体策略方法不是> 策略的变体,因为它具有不同的返回类型。
如果这样的事情可以通过像指向任何东西的指针这样的黑客来实现,那么你就会遇到下一个问题。因此,让我们定义任何东西都可以简化为数据对象
。
您的具体文件解析器读取策略方法提供了大量不同的数据对象
类型,这些类型必须在程序中的某个位置进行描述才能处理此类数据。提示:您的数据对象
将具有哪种类型的接口(interface)?也许您想读取一些 int
值,但也想读取 std::string 对象和容器类。这些类型有通用接口(interface)吗?
如果您的数据类型没有这样一个通用接口(interface),您只需打破一般的 OOP 设计规则:永远不要从外部查看类/对象内部的细节。您的解决方法可能是这样的:
switch ( dataobject[n].getType() )
{
case INT:
...;
case STRING:
...;
... and all the objects you have defined yourself!
}
您现在编写如下代码:
auto parser1.getResults();
您的结果必须始终相同。 auto 并不意味着它可以在运行时改变它的类型。所以这不是这里的解决方案。
下一个问题: 您的程序代码似乎对文件的内容做出了一些假设。策略模式的用户必须知道对象如何以具体顺序存储在文件中。更好的方法是对象包含一些内容,并且解析器可以处理它。但这里的策略模式并不正确。
我的提示: 如果您的设计独立于任何设计模式,导致定义一个类层次结构,其中包含一些必须具有不同返回类型的虚函数(这是不可能的),那么您的设计就被破坏了!
关于c++ - 使用类似策略模式的文件解析器 - 如何获得结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31558686/