Reputation: 76519
I have a class Target
with a "fileType" enum
which holds all kinds of files my parser needs to know about (currently SOURCE, HEADER, RESOURCE). I'd like my Parsing function to be able to do something generic like:
if( token == some_known_fileType )
put_nextToken_in_the_list_for_that_fileType();
else
return an_error();
But there's a catch: I'd like to be able to simply extend the known fileTypes with subclasses of Target
, that extend the enum
in a correct way, see Base enum class inheritance for how I did this. I don't want to modify the above code, but only generically extend the Target half. C++0X may be required and is very welcome.
Thanks!
UPDATE: Upon trying to explain it here and posting some reduced class declarations, I realised my design is broken, and I tried to push the specialization of fileType too deep in my class structure. I wanted only one place to store a full list of all known types, but in trying to do so, I accidentally forced the design to have access to that list in two places at a time. I now realise that the list of all fileTypes should be where the keywords SOURCE, HEADER, etc. are read, and be handled *generically from thereon. I will store a full list in one place, and access that list through a "huge" enum
later on. A std::map<fileType, std::set<std::string> >
pops into my head as a logical choice here, instead of seperately named set
for each specific fileType
. Thanks for the braincandy in your responses though! Any thoughts are still welcome.
Upvotes: 0
Views: 716
Reputation: 315
I believe this is not usually the right approach, but that's my belief. I would do this in a different way. Take a step back and what are we trying to achieve, we want to control the behavior based on an incoming (input parameter) value. Lets say we have classes: FileA FileB ... the file_type holds the type of file. Use a factory to control the available list of files (which can change based on the registration of different files).
class FileA {
void register_type(); // register itself to the factory.
};
class FileB..
//main code
class FileFactoryDelegator {
...
delegateControl (FileType file_type) {
//validate file_type.
file_types[file_type]->performFileOperation (..);
}
};
Instead of if-else loop.
file_factory.delegateControl (token);
Upvotes: 2
Reputation: 1387
This is hard to answer as a lot depends on what exactly your are doing with the tokens, file type values, and Target instances. However, I think the underlying theme here is that you need to replace if() statements with virtual method calls. For example, your code fragment could end up being
if (tokenLists.supportsFileType(token))
tokenLists.getListForType(token).put_nextToken_into_this_list();
else
return an_error();
The above tokenLists example could be generalized into a registry of TargetSpecificLogic instances, which combine all kinds of filetype specific methods.
You Target class could implement a virtual method retrieveAllKnownFileTypes()
, which the subclasses would extend, and which the rest of your code could evaluate.
You Target class could implement a virtual method bool isFileTypeKnown(filetype)
, returning true
or false
.
...and so on.
Upvotes: 0