Question

I need to implement an interface for a class in C++ where I need to ask for events occured related with two kinds of sets, let's say here persons and actions. I need to ask for person identifier and action identifier in all possible combinations (all of them, specifying only one of the identifiers or specifying both of them)
Option 1)

// Asks for all events occured for every combination
int getNumberofEvents(float param1)
// Asks for all events occured for idPerson AND all possible value of idAction
int getNumberofEvents(int idPerson, float param1)  
// Asks for all events occured in idAction AND all possible value of idPerson
int getNumberofEvents(int idAction, float param1)
// Asks for all events occured in idPerson AND idAction
int getNumberofEvents(int idPerson, int idAction, float param1)

This option is clear to read but I need to implement a different interface for every possible combination, so there would be 8 methods if I include a new identifier (2³).

Option 2)

static const int ALL_PERSONS= 0;
static const int ALL_ACTIONS= 0;
int getNumberofEvents(int idPerson, int idAction, float param1)

For this option there is only one method interface, but I introduce a public magic number to search for 'All possible id'

Regarding to usability and further maintainability, which would be the best option between these two now I have in mind (there can be other better options that I do not include, of course).

Thanks.

Était-ce utile?

La solution

You could modify option 2 to avoid magic numbers and also avoid the problem of passing a person id for the action parameter or vice versa:

struct Person
{
    explicit Person(int x) : id (x) {}
    int id;
    static Person ALL;
};

Person Person::ALL(0);

struct Action
{
    explicit Action(int x) : id (x) {}
    int id;
    static Action ALL;
};

Action Action::ALL(0);

int getNumberofEvents(const Person& person, const Action& action, float param1);

// ...

int count = getNumberOfEvents(Person(3), Action::ALL, 1.0f);

Autres conseils

You appear to be badly reinventing what C++ has included in the Standard Library: std::count_if

Notice that it allows arbitrarily complex conditions because it accepts a functor object which is able to filter and decide which objects match. With C++11, lambdas make supplying the condition easier than ever.

You can either expose begin() and end() iterators and let the user call std::count_if, or write

int getNumberofEvents(std::function<bool (const descriptor&)> filter, float param1);

and let the user write their query expression in a very natural way:

getNumberOfEvents([](const descriptor& x) { return x.Action == ACTION_RAISE; }, 5.7);

Absolutely go with option 2. The user of your code won't have to look up which method they want to call, they would just be able to use your defined constants in certain cases. It makes the user's life a whole lot easier to only have one function name to work with so that they don't have to be constantly referencing your .h file to figure out which one of the many functions (named the same thing) they want to use.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top