I am developing a partition tool, and I am facing a problem in the design. I have a class (called CtrlFactories) that will read the MBR and build an object for each partition that is found in the MBR. I have a class for each type of partition and a Factory for each of them.
Here is how it looks like:

(I’ve put only NTFS and FAT32 in the example, but I have one for each type of partition).
My idea was to put in the IFactory something like:
std::map< EPartType, IFactory* > mpFactories;
And build it in the constructor, or in some init function:
IFactory::IFactory()
{
mpFactories[PART_NTFS] = new FactoryNTFS();
mpFactories[PART_FAT32] = new FactoryFAT32();
mpFactories[PART_EXT2] = new FactoryEXT2();
...
}
And in the “Build” function, do:
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
}
}
The point is: I have lots of partition types (> 100), and in most of cases, the user will only have two or three different types of partitions in the HD. So it seems like a waste of time and memory to allocate all the factories and not using most of them. I think that a lazy initialization would be much better here, but then I would need somewhere a code like:
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;
...
}
}
And that very long switch/case would add too much ciclomatic complexity to the code (even the code being easy to understand).
So, is there a better solution for the problem, that can avoid the very long “switch/case” and that does not waste resources?
One approach would be to implement the factories with the Singleton pattern. Have a static
Instance()method on each factory class that manages it’s instantiation. Then in your map you could store a function pointer to that method.In your
Build()code you’re then looking up a pointer to theInstance()method for the factory for each partition you come across. Use that pointer to get the actual factory you need, and then proceed from there.