Я занимаюсь разработкой инструмента для создания разделов и столкнулся с проблемой в дизайне. У меня есть класс (называемый CtrlFactories), который будет читать MBR и создавать объект для каждого раздела, который находится в MBR. У меня есть класс для каждого типа раздела и Фабрика для каждого из них.
Вот как это выглядит:
(в примере я поместил только NTFS и FAT32, но у меня есть один для каждого типа раздела).
Моя идея заключалась в том, чтобы поместить в IFactory что-то вроде:
std::map< EPartType, IFactory* > mpFactories;
И встроить его в конструктор или в некоторую функцию инициализации:
IFactory::IFactory()
{
mpFactories[PART_NTFS] = new FactoryNTFS();
mpFactories[PART_FAT32] = new FactoryFAT32();
mpFactories[PART_EXT2] = new FactoryEXT2();
...
}
А в функции «Сборка» выполните:
int CtrlFactories::Build()
{
...
MBR mbr;
BuildMBR( mbr );
//... here I loop all the partitions found...
for( /*each partition*/ )
{
IPartition* part = mpFactories[ mbr.GetPartType() ]->Build( mbr.PartPosition() );
//..and store each partition somewhere
}
}
Дело в том, что у меня много типов разделов (> 100), и в большинстве случаев у пользователя будет только два или три различных типа разделов в HD. Таким образом, это кажется пустой тратой времени и памяти, чтобы распределить все фабрики и не использовать большинство из них. Я думаю, что ленивая инициализация была бы здесь намного лучше, но тогда мне понадобился бы где-нибудь код вроде:
switch( mbr.GetPartType() )
{
case PART_NTFS:
if ( mpFactories[ PART_NTFS ] == NULL )
mpFactories[PART_NTFS] = new FactoryNTFS();
break;
case PART_FAT32:
if ( mpFactories[ PART_32 ] == NULL )
mpFactories[PART_32] = new Factory32();
break;
...
}
* *} Тысяча двадцать-один
И этот очень длинный переключатель / регистр привнесет в код слишком много цикломатической сложности (даже кода, который легко понять).
Итак, есть ли лучшее решение для проблемы, которое может избежать очень длинного "переключателя / случая" и которое не тратит впустую ресурсы?