C++ Design – Calling Different Library Functions Based on Parameters

cdesignfunctions

I am writing a rather large class where the user can specify at runtime whether she wants to use algorithm A or B of an third party library e.
Basically there is only one function call different in choosing A or B, but this function is called in many different places in the code.

I would like to omit having to write

if (user_chose_A) {
  call_A_algo();
} else {
  call_B_algo();
}

all over my code and I am wondering what's a nice solution for my problem (in C++11).

I was thinking about storing two function pointers (std::function), one to algorithm A and one to B and then have one function in my class which returns the correct function pointer.

Since my scenario seems like a rather common situation, I am wondering what's best practice here.

Best Answer

The common object-oriented approach for hiding implementation details (in this case A_algo and B_algo are implementation details) is to find a connection between the two (or among three or more) functions and to define a new generic interface (in C++ a pure abstract class), which is then instantiated by some sort of a factory.

In object-oriented terms, this is mostly refered to as the adapter design pattern, when you provide same interface for two seemingly different things.

class AlgorithmAdapter
{
public:
    virtual void run() const = 0;
};

class AlgorithmOneAdapter : public AlgorithmAdapter
{
public:
    void run() const
    {
        call_A_algo();
    }
};

class AlgorithmTwoAdapter : public AlgorithmAdapter
{
public:
    void run() const
    {
        call_B_algo();
    }
};

// some function
void runsAlgorithm(AlgorithmAdapter const & algorithm)
{
    algorithm.run(); // <- does not care whether it's algo_A or algo_B,
                     // but it knows, the run method is available
}

You would then have the factory, which would contain a switch statement, providing a concrete implementation of AlgorithmAdapter interface, on which you'd know the run method is available.


Why is this good?

You delegate the algorithm decision from your business logic layer to a factory class, which is only responsible for object graph creation (see separation of concerns).

Is it worth it?

Creating 3 or more classes just so you can abstract the call? Maybe even not, depends on your requirements.

Is there an easier way?

I mentioned a factory, which is pretty much just a simple switch/case function/method. You can do the same without having to define the 3 new adapter classes, by defining a new function/metod, putting the decision in there based on a parameter value that is being passed and using this method throughout your code (working with functions directly is more procedural approach than object-oriented one).

It is much faster to get done, but kind of mixes responsibilities (with that approach you'd have a function which would do both, make the decision which algorithm should be chosen and run it).

You could also pass a function pointer as a parameter to a function, thus in a function you'd be specific algorithm ignorant, but even then, you'd still have to make the decision which algorithm to choose somewhere. No matter how hard you'll try, there will always be place in a code which will know how to wire components together based on some rules, it's inevitable.