Я бы разделил преобразование строк в enum в отдельный объект. Это может быть легко решено с помощью карты, кстати. Но обработка ошибок и т. Д. - все еще то, о чем ни D, ни фабрика не должны беспокоиться.
Затем либо D вызывает конвертер для получения его перечисления, либо он уже преобразован заранее, поэтому D нужно только передать перечисление на завод. (Кстати, на заводе лучше использовать карту вместо внутреннего переключателя).
Возникает вопрос: действительно ли вам нужны перечисления вообще (в местах, отличных от D и фабрики)? Если нет, то, возможно, перечисление можно было бы оставить вне рисунка, и вы могли бы использовать карту для преобразования непосредственно из строк в типы (т. Е. Поскольку C ++ не поддерживает динамическую загрузку классов) для функций объектов, которые создают необходимые конкретные экземпляры типов для вы). Грубый пример (у меня нет IDE для тестирования, так что потерпите меня, если в нем есть ошибки):
// Function type returning a pointer to B
typedef (B*)(*func)() StaticConstructor;
// Function creating instances of subclass E
B* createSubclassE() {
return new E(...);
}
// Function creating instances of subclass F
B* createSubclassF() {
return new F(...);
}
// Mapping from strings to constructor methods creating specific subclasses of B
map<string, StaticConstructor> factoryMap;
factoryMap["E"] = &createSubclassE;
factoryMap["F"] = &createSubclassF;
Конечно, созданные экземпляры также должны утилизироваться должным образом - в рабочем коде возвращаемые объекты могут быть, например, заключено в auto_ptr
. Но я надеюсь, что этого короткого примера достаточно, чтобы показать вам основную идею. Вот учебник , если вы хотите больше ...