mercredi 19 août 2020

How to refactor this 'command handler map' from derived classes to the base class?

I am trying to refactor some C++ code by moving certain common functionality from derived classes to the base class. Say I have a base class Fruit and two derived classes Apple and Orange. Both derived classes currently hold a private map that maps commands to member functions, e.g. for the Apple class this would be

typedef void (Apple::*CommandHandler)();
static const std::map<std::string, CommandHandler> commandhandlers;

As the commandhandlers map does not change over time, I've made it static and for each derived class it gets filled with commandhandlers using a static function, e.g. for the Apple class:

static std::map<std::string, Apple::CommandHandler> mpInitCommandHandlerMap()
{
    std::map<std::string, Apple::CommandHandler> commandhandlers;
    commandhandlers.insert(std::make_pair("eat", &Apple::eat));
    // ... and so on...
    return commandhandlers;
}

where

void eat() { std::cout << "eating apple" << std::endl; }

is an example of a (private) command handler for the eat command in the Apple class.

Both the Apple and the Orange derived classes also have a handle function to handle different commands:

void handle(const std::string& command)
{
    const auto handler = commandhandlers.at(command);
    (this->*handler)();
}

Since this handle function is the same for both derived classes, I want to move it to the Fruit class. However, that is where I'm stuck. The commandhandlers map currently exists in both the Apple and the Orange class, and with different types for the command handler functions (typedef void (Apple::*CommandHandler)(); for the Apple class and typedef void (Orange::*CommandHandler)(); for the Orange class).

So my question is: I want to have only one commandhandler map and one handle function in the Fruit class. How do I do this (preferably using C++14 for now)? The full code is available online at https://godbolt.org/z/87zbGa

Aucun commentaire:

Enregistrer un commentaire