我正在设计一个Win32库来解析文件的内容(列和值),并将其内部存储在数据结构(Map)中。现在我需要公开API,以便消费者可以调用这些API来获得结果。
文件可能有不同的格式,例如FM1,FM2等。消费者可能会查询
FM1Provider.GetRecords("XYZ");
FM2Provider.GetRecords("XYZ");
我打算做的是让一个CParser类完成所有解析并公开该类。
CParser
{
bool LoadFile(string strFile);
Map<string,string> GetFM1Records(string key);
Map<string,string> GetFM1Records(string key);
};
或
class CResultProvider
{
virtual Map<string,string> GetRecords(string key)=0;
}
class CFM1ResultProvider : public CResultProvider
{
Map<string,string> GetRecords(string key);
}
class CFM2ResultProvider : public CResultProvider
{
Map<string,string> GetRecords(string key);
}
CParser
{
bool LoadFile(string strFile);
CResultProvider GetFM1ResultProvider();
CResultProvider GetFM1ResultProvider();
};
考虑到我正在开发一个库,请建议我这些方法中的哪一种是正确和可扩展的。
答案 0 :(得分:2)
您的组件似乎正在处理两个问题:解析和存储。将这些组件分成不同的组件是一种很好的设计实践,以便它们可以独立使用。
我建议您仅为解析数据提供回调。这样,它的用户可以为她的应用程序选择最合适的容器,或者可以选择在不存储的情况下应用和丢弃读取的数据。
E.g:
namespace my_lib {
struct ParserCb {
virtual void on_column(std::string const& column) = 0;
virtual void on_value(std::string const& value) = 0;
protected:
~ParserCb() {} // no ownership through this interface
};
void parse(char const* filename, ParserCb& cb);
} // my_lib
BTW,更喜欢使用名称空间而不是prefixing your classes with C。
答案 1 :(得分:1)
假设客户只需要调用GetRecords
一次,然后使用地图,第一种方法我更喜欢第一种方法,因为它更简单。
如果客户端必须在其代码中的不同位置重新加载地图,则第二种方法更可取,因为它使客户端能够针对一个接口(CResultProvider
)编写代码。因此,他只需选择一个不同的实现就可以轻松切换文件格式(在他的代码中应该只有一个地方可以选择实现)。