Right, the identity function is just a dummy adapter for the simple degenerate case.
Generate a report, given any one of the following data sources:
AccountingDataSource companyExpenseList;
SantasNaughtyOrNiceList santasList;
HitList hitList;
Without adapters:
void GenerateReport(DataSource& dataSource) {
...
for (auto& row : dataSource) {
std::string userName = "";
if (accountingRow = dynamic_cast<AccountingRow&>(row)) {
userName = accountingRow.expenseIncurredBy;
} else if (naughtyInfo = dynamic_cast<NaughtInfo&>(row)) {
userName = naughtyInfo.kidName;
} else if (name = dynamic_cast<String&>(row)) {
userName = name;
}
...
}
...
}
GenerateReport(oneOfTheDataSources);
With adapters, but lacking identity:
void BuildReport(DataSource& dataSource, UsernameFn* getUserName) {
...
for (auto& row : dataSource) {
auto userName = getUserName(row);
std::string userName = "";
if (getUserName != null) {
userName = getUserName(row)
} else {
userName = row;
}
...
}
...
}
std::string accountingExpenseUserName(AccountingRow& row) { return row.expenseIncurredBy; }
std::string accountingPaidToUserName(AccountingRow& row) { return row.paidTo; }
GenerateReport(companyExpenseList, accountingExpenseUserName);
GenerateReport(companyExpenseList, accountingPaidToUserName);
GenerateReport(hitList, null);
With adapters, and identity function:
void BuildReport(DataSource& dataSource, UsernameFn* getUserName) {
...
for (auto& row : dataSource) {
auto userName = getUserName(row);
...
}
...
}
std::string accountingExpenseUserName(AccountingRow& row) { return row.expenseIncurredBy; }
std::string accountingPaidToUserName(AccountingRow& row) { return row.paidTo; }
std::string identityFunction(std::string name) { return name; }
GenerateReport(companyExpenseList, accountingExpenseUserName);
GenerateReport(companyExpenseList, accountingPaidToUserName);
GenerateReport(hitList, identityFunction);
You'll notice the hitman isn't too picky about the identity function.
