A resposta aceita é boa quando você tem apenas 3 casos e a lógica de cada um é simples.
Mas se a lógica de cada caso for mais complicada ou se houver muitos outros casos, uma opção muito melhor é usar o padrão de design da cadeia de responsabilidades .
Você cria um BaseValidator
que contém uma referência a BaseValidator
e um método validate
e um método para chamar a validação no validador referenciado.
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;
}
}
Em seguida, você cria um número de subclasses que herdam BaseValidator
, substituindo o validate
método pela lógica necessária para cada validador.
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);
}
}
Em seguida, usá-lo é simples, instancie cada um dos seus validadores e defina cada um deles como a raiz dos outros:
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)) { ... }
Em essência, cada caso de validação possui sua própria classe, responsável por (a) determinar se a validação corresponde àquela caso, e (b) enviar a validação para outra pessoa na cadeia, se não for.
Observe que eu não estou familiarizado com C ++. Eu tentei combinar a sintaxe de alguns exemplos que encontrei online, mas se isso não funcionar, trate-o mais como pseudocódigo. Eu também tenho um exemplo completo de trabalho em Python abaixo que pode ser usado como base, se preferir.
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))
Novamente, você pode encontrar esse exagero no seu exemplo específico, mas ele cria um código muito mais limpo se você acabar com um conjunto de casos muito mais complicado que precisa ser atendido.
if
declaração complexa . Além disso, como são sinalizadores booleanos, é possível modelar cada cenário como uma constante e comparar com ele.