Принятый ответ хорош, если у вас всего 3 случая и логика для каждого проста.
Но если логика для каждого случая была более сложной или случаев намного больше, гораздо лучшим вариантом было бы использовать шаблон проектирования цепочки ответственности .
Вы создаете, BaseValidator
который содержит ссылку на, BaseValidator
а также метод validate
и метод для вызова проверки на указанном валидаторе.
class BaseValidator {
BaseValidator* nextValidator;
public:
BaseValidator() {
nextValidator = 0;
}
void link(BaseValidator validator) {
if (nextValidator) {
nextValidator->link(validator);
} else {
nextValidator = validator;
}
}
bool callLinkedValidator(bool v1, bool v2, bool v3, bool v4) {
if (nextValidator) {
return nextValidator->validate(v1, v2, v3, v4);
}
return false;
}
virtual bool validate(bool v1, bool v2, bool v3, bool v4) {
return false;
}
}
Затем вы создаете несколько подклассов, которые наследуются от метода BaseValidator
, переопределяя validate
его логикой, необходимой для каждого валидатора.
class Validator1: public BaseValidator {
public:
bool validate(bool v1, bool v2, bool v3, bool v4) {
if (v1 && v2 && v3 && v4) {
return true;
}
return nextValidator->callLinkedValidator(v1, v2, v3, v4);
}
}
Затем использовать его просто: создайте экземпляр каждого из ваших валидаторов и установите каждый из них в качестве корня для других:
Validator1 firstValidator = new Validator1();
Validator2 secondValidator = new Validator2();
Validator3 thirdValidator = new Validator3();
firstValidator.link(secondValidator);
firstValidator.link(thirdValidator);
if (firstValidator.validate(value1, value2, value3, value4)) { ... }
По сути, каждый случай проверки имеет свой собственный класс, который отвечает за (а) определение того, соответствует ли проверка этому случаю, и (б) отправка валидации кому-то еще в цепочке, если это не так.
Обратите внимание, что я не знаком с C ++. Я попытался сопоставить синтаксис с некоторыми примерами, которые нашел в Интернете, но если это не сработает, относитесь к нему как к псевдокоду. У меня также есть полный рабочий пример Python ниже, который при желании можно использовать в качестве основы.
class BaseValidator:
def __init__(self):
self.nextValidator = 0
def link(self, validator):
if (self.nextValidator):
self.nextValidator.link(validator)
else:
self.nextValidator = validator
def callLinkedValidator(self, v1, v2, v3, v4):
if (self.nextValidator):
return self.nextValidator.validate(v1, v2, v3, v4)
return False
def validate(self, v1, v2, v3, v4):
return False
class Validator1(BaseValidator):
def validate(self, v1, v2, v3, v4):
if (v1 and v2 and v3 and v4):
return True
return self.callLinkedValidator(v1, v2, v3, v4)
class Validator2(BaseValidator):
def validate(self, v1, v2, v3, v4):
if (v1 and v2 and v3 and not v4):
return True
return self.callLinkedValidator(v1, v2, v3, v4)
class Validator3(BaseValidator):
def validate(self, v1, v2, v3, v4):
if (v1 and not v2 and not v3 and not v4):
return True
return self.callLinkedValidator(v1, v2, v3, v4)
firstValidator = Validator1()
secondValidator = Validator2()
thirdValidator = Validator3()
firstValidator.link(secondValidator)
firstValidator.link(thirdValidator)
print(firstValidator.validate(False, False, True, False))
Опять же, вы можете найти это излишество для своего конкретного примера, но он создает гораздо более чистый код, если в конечном итоге вы получите гораздо более сложный набор случаев, которые необходимо выполнить.
if
оператора. Кроме того, поскольку это логические флаги, вы можете моделировать каждый сценарий как константу и проверять его.