У меня есть приложение с интерфейсом командной строки, к которому я добавляю графический интерфейс. Часто возникает ситуация, когда у меня есть список объектов, которые наследуются от одного класса и должны отображаться в списке, но каждый подкласс имеет немного другой способ отображения.
Не желая иметь повсюду гигантские операторы switch, использующие отражение / RTTI для отображения, каждый класс знает, как вернуть свою собственную итоговую строку, которая затем отображается в списке:
int position = 0;
for (vector<DisplayableObject>::const_iterator iDisp = listToDisplay.begin(); iDisp != listToDisplay.end(); ++iDisp)
cout << ++position << ". " << iDisp->GetSummary();
Аналогичные функции существуют для отображения различной информации в разных контекстах. Это было все хорошо, пока нам не нужно было добавить графический интерфейс. Строка больше не достаточно - мне нужно создать графические элементы управления.
Я не хочу изменять каждый отдельный класс, чтобы иметь возможность отображать его в графическом интерфейсе, тем более, что существует по крайней мере еще одна платформа графического интерфейса, к которой мы хотим переместить это.
Есть ли какая-то техника, которую я могу использовать, чтобы отделить этот код GUI от объектов данных, не прибегая к RTTI и операторам switch? Было бы неплохо иметь возможность также использовать функции GetSummary.
В идеале я бы мог иметь иерархию классов отображения, которая могла бы брать класс данных и отображать его на основе типа времени выполнения вместо типа времени компиляции:
shared_ptr<Displayer> displayer = new ConsoleDisplayer();
// or new GUIDisplayer()
for (vector<DisplayableObject>::const_iterator iDisp = listToDisplay.begin(); iDisp != listToDisplay.end(); ++iDisp)
displayer->Display(*iDisp);