Мне нужно реализовать интерфейс для класса в C ++, где мне нужно запрашивать события, связанные с двумя видами наборов, скажем, здесь люди и действия. Мне нужно запросить идентификатор лица и идентификатор действия во всех возможных комбинациях (все из них, указав только один из идентификаторов или указав оба)
Опция 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)
Эта опция понятна для чтения, но мне нужно реализовать разные интерфейсы для каждой возможной комбинации, поэтому было бы 8 методов, если бы я включил новый идентификатор (2³).
Вариант 2)
static const int ALL_PERSONS= 0;
static const int ALL_ACTIONS= 0;
int getNumberofEvents(int idPerson, int idAction, float param1)
Для этой опции есть только один интерфейс метода, но я ввожу общедоступный магический номер для поиска «Все возможные идентификаторы».
Что касается юзабилити и дальнейшей ремонтопригодности, что было бы лучшим вариантом между этими двумя, которые я сейчас имею в виду (могут быть и другие, более лучшие варианты, которые я, конечно, не включаю).
Благодарю.
Вы можете изменить вариант 2, чтобы избежать использования магических чисел, а также избежать передачи идентификатора человека для параметра действия или наоборот:
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);
Вы, кажется, плохо изобретаете то, что C ++ включил в стандартную библиотеку: std::count_if
Обратите внимание, что он допускает произвольно сложные условия, потому что он принимает объект-функтор, который способен фильтровать и решать, какие объекты соответствуют. В C ++ 11 лямбда-выражения делают условие проще, чем когда-либо.
Вы можете либо выставить begin()
а также end()
итераторы и пусть пользователь вызывает std::count_if
или напишите
int getNumberofEvents(std::function<bool (const descriptor&)> filter, float param1);
и пусть пользователь напишет свое выражение запроса очень естественным образом:
getNumberOfEvents([](const descriptor& x) { return x.Action == ACTION_RAISE; }, 5.7);
Абсолютно перейдите к варианту 2. Пользователю вашего кода не нужно будет искать, какой метод он хочет вызвать, он просто сможет использовать ваши определенные константы в определенных случаях. Это значительно облегчает жизнь пользователя, когда у него есть только одно имя функции, поэтому ему не нужно постоянно ссылаться на ваш файл .h, чтобы выяснить, какую из многих функций (названных одинаково) они хотят получить. использовать.