Я часто сталкиваюсь с методами, которые имеют одинаковую структуру и логику, но с некоторыми отличиями, и я не нахожу правильный способ не повторяться.
Например:
void ChannelSelection::selectAlmostOkChannels(int currentInkId)
{
bool selected = true;
foreach (auto report, m_reports) {
if (report.scoreByInk.find(currentInkId) != report.scoreByInk.end()) {
auto tmpStatus = Assessment::getStatusFromScore(report.scoreByInk.value(currentInkId));
if (tmpStatus == Assessment::Ok)
selected = false;
else if (tmpStatus == Assessment::NotOk)
m_autoSelection[report.name].setSelected(currentInkId, false);
}
}
m_currentSelection.insert(currentInkId, selected);
}
void ChannelSelection::selectNotOkChannels(int currentInkId)
{
bool selected = true;
foreach (auto report, m_reports) {
if (report.scoreByInk.find(currentInkId) != report.scoreByInk.end()) {
auto tmpStatus = Assessment::getStatusFromScore(report.scoreByInk.value(currentInkId));
if (tmpStatus == Assessment::Ok || tmpStatus == Assessment::AlmostOk)
selected = false;
}
}
m_currentSelection.insert(currentInkId, selected);
}
Как видите, эти две функции очень похожи (отличается только внутренняя функция).Как я могу красиво удалить дублирование в этом коде?
Одним из решений, о котором я подумал, является использование функтора, что-то вроде:
void ChannelSelection::selectChannels(int currentInkId, std::function<bool()> fn)
{
bool selected = true;
foreach (auto report, m_reports) {
if (report.scoreByInk.find(currentInkId) != report.scoreByInk.end()) {
auto tmpStatus = Assessment::getStatusFromScore(report.scoreByInk.value(currentInkId));
selected = fn();
}
}
m_currentSelection.insert(currentInkId, selected);
}
Вызывающая сторона получает ответственность за реализацию функтора.Есть ли альтернатива без этой проблемы?