vendredi 15 mai 2015

Pattern for choosing behaviour based on the types present in a collection derived objects

I have an collection of objects which represents a model of a system. Each of these objects derives from a base class which represents the abstract "component". I would like to be able to look at the system and choose certain behaviours based on what components are present and in what order.

For the sake of argument, let's call the base class Component and the actual components InputFilter, OutputFilter and Processor. Systems that we can deal with are ones with a Processor and one or both filters. The actual system has more types and more complex interaction between them, but I think this will do for now.

I can see two "simple" ways to handle this situation with a marshalComponentSettings() function which takes one of the collections and works out how to most efficiently set up each node. This may require modifying inputs in certain ways or splitting them up differently, so it's not quite as simple as just implementing a virtual handleSettings() function per component.

  • The first is to report a enumerated type from each class using a pure virtual function and use those to work out what to do, dynamic_cast'ing where needed to access component specific options.

    enum CompType { INPUT_FILTER, OUTPUT_FILTER, PROCESSOR }

    void marshal(Settings& stg) { if (comps[0].type == INPUT_FILTER) setUpInputFilter(stg); //maybe modified the stg, or provides other feedback of what was done

    // something similar for outputs
    
    setUpProcessor(stg);
    
    

    }

  • The second is to dynamic_cast to anything that might be an option in this function and use the success of that or not (as well as maybe the cast object if needed) to determine what to do.

It seems that the first is the most efficient way (don't need to speculatively test each object to find out what it is), but even that doesn't quite seem right (maybe due to the annoying details of how those devices affect each other leaking into the general marshaling code).

Is there a more elegant way to handle this situation than a nest of conditionals determining behaviour? Or even a name for the situation or pattern?

Aucun commentaire:

Enregistrer un commentaire