2011-10-13 24 views
1

我正在設計一個Win32庫來解析文件(列和值)的內容並將其存儲在數據結構(映射)中。現在我需要公開API,以便消費者可以調用這些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(); 
    }; 

請給我建議這些方法之一是正確的,可擴展的考慮我正在開發一個圖書館。

回答

1

假設客戶端只需要撥打GetRecords一次,然後使用地圖,第一種方法我更喜歡第一種方法,因爲它更簡單。

如果客戶端必須在其代碼中的不同位置重新加載地圖,則第二種方法更可取,因爲它使客戶端能夠在一個接口(CResultProvider)上編寫他的代碼。因此,他可以簡單地通過選擇不同的實現來輕鬆切換文件格式(在他的代碼中應該只有一個地方選擇實現)。

2

你的組件似乎在處理兩個問題:解析和存儲。將它們分成不同的組件是一個很好的設計實踐,以便它們可以獨立使用。

我建議你只提供解析數據的回調解析器。這樣它的用戶可以爲她的應用程序選擇最合適的容器,或者可以選擇應用並丟棄讀取數據而不存儲。

例如爲:

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命名空間。

+0

+1:他可以製作採用輸出迭代器(其類型是模板參數)的解析器函數模板,以便將數據寫入其中。如果他想讓他們成爲虛擬功能,這當然是有問題的。 –

+1

回調更靈活,然後輸出迭代器,因爲解析器可能吐出多種類型的元素。 –

+0

@Maxim:同意,我將有一個暴露的類CMylib。其他兩個只能分析的類CParser和存儲解析數據的CDatastore。我將創建CDataStore作爲CMyLib類的成員變量,並且CParser類將在解析時實例化,並在解析後立即刪除。現在的問題是,我應該如何公開API以確保數據庫的數據庫?所以現在你可以考慮在我之前的例子中,CParser被CMyLib – Jeeva