狡猾的代码嗅觉解决(由于两个单独的库)c + +

我有一个程序,将excel转换为数据,每次读取一个单元格,逐行迭代。

要做到这一点,我一直在使用两个单独的库:

ExcelFormat(用于xls)

Xlsx I / O

我有一个抽象类的algorithm,并为每个派生类。 我遇到的问题是ExcelFormat和Xlsx I / O不遵循相同的格式(因为它们是单独的库,并不符合相同的基类)。

(注意,我为xlsxio编写了一个包装程序,因为它是程序化的,而且我想要OOfunction)

我想尽可能地将algorithm抽象到基类。

就目前而言,我真正能够做的就是拥有通用的抽象方法Convert(),这非常糟糕,因为这两个函数algorithm非常相似,但是不能简单地遵从统一的接口,因为它们不要共享相同的基础。

这是我有:

bool XlsxToData::Convert(const std::string & filePath, std::list<SqlParam*>* params) { FreeXlsx::XlsxBook book(filePath); if (book.IsOpen()) { std::vector<std::string>* sheets = book.GetSheetList(); if (sheets != nullptr) { std::list<SqlParam*> foundParams; for (auto itr : *sheets) { FreeXlsx::XlsxSheet sheet(itr, book); std::map<int, SqlParam*> foundX; int longestWidth = 0; int lastWidth = 0; if (sheet.IsOpen()) { sheet.ForSheet([this, &foundParams, &foundX, &longestWidth, &lastWidth, params](const std::string & value, const int & x, const int & y) { if (x > longestWidth) longestWidth = x; lastWidth = x; GetValueCell(foundX, value, x); CheckParams(foundX, foundParams, value, x, params); }, [&longestWidth, &lastWidth, &foundX, this](const int & row) { if (lastWidth < longestWidth) for (int i = lastWidth + 1; i <= longestWidth; ++i) { auto find = foundX.find(i); if (find != foundX.end()) { find->second->PushValue(""); } } }); sheet.Close(); } if (params->size() < 1) break; } delete sheets; while (foundParams.size() > 0) { params->push_back(*foundParams.begin()); foundParams.erase(foundParams.begin()); } } book.Close(); return true; } return false; } bool XlsToData::Convert(const std::string & filePath, std::list<SqlParam*>* params) { ExcelFormat::BasicExcel book; if (book.Load(filePath.c_str())) { int sheets = book.GetTotalWorkSheets(); std::list<SqlParam*> foundParams; for (int i = 0; i < sheets; ++i) { ExcelFormat::BasicExcelWorksheet* sheet = book.GetWorksheet(i); std::map<int, SqlParam*> foundX; if (sheet != nullptr) { const int rows = sheet->GetTotalRows(); const int cols = sheet->GetTotalCols(); std::map<int, SqlParam*> foundX; for (int row = 0; row < rows; ++row) { bool willBreak = false; for (int col = 0; col < cols; ++col) { ExcelFormat::BasicExcelCell * cell = sheet->Cell(row, col); if (cell != nullptr) { std::string value = getval(cell); GetValueCell(foundX, value, col); CheckParams(foundX, foundParams, value, col, params); } } if (willBreak) break; } } } while (foundParams.size() > 0) { params->push_back(*foundParams.begin()); foundParams.erase(foundParams.begin()); } book.Close(); return true; } return false; } 

我希望能够抽象的方法来打开书籍/工作表成为单一的方法作为迭代每个细胞的过程。

我已经考虑过可能修改ExcelFormat和Xlsx I / o的Wrapper类的来源,以统一的抽象基础进行操作。

这是否是最明智的方式呢?

这种冲突有没有devise模式?

我是否应该实现从Excel格式类inheritance的适配器类,然后使用Xlsxio包装器,并且新的适配器类符合新的抽象基础?

还是有没有人有更好的解决scheme?

谢谢。

编辑:另外,边注,我意识到这显然有很长的方法代码的气味。 我打算用更广义的algorithm来重构这个。

你有没有考虑使用https://sourceforge.net/projects/xlslib/ ? 它稍微过时了,更便于携带。

对于XLSX I / OI,如果需要遍历所有单元格(包括空单元格),则build议使用xlsxioread_process的XLSXIOREAD_SKIP_NONE标志。

其余的我认为编写一个通用的基类并不像你说的那样明显,因为库之间的方法不同。

我的build议是使抽象类尽可能抽象,这意味着你不应该基于任何一个库,而只是它们的共同属性。

就我个人而言,我已经放弃了.xls的支持,因为这是Microsoft自Office 2007以来不再使用的封闭格式。