Прийнята відповідь чудова, коли у вас є лише 3 випадки, і де логіка для кожного проста.
Але якщо логіка для кожного випадку була складнішою, або є набагато більше випадків, набагато кращим варіантом є використання схеми проектування ланцюжка відповідальності .
Ви створюєте, BaseValidator
що містить посилання на a, 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)) { ... }
По суті, у кожному випадку перевірки є свій клас, який відповідає за (a) визначення, чи відповідає валідація цьому випадку, і (b) відправлення перевірки комусь іншому в ланцюжку, якщо це не так.
Зверніть увагу, що я не знайомий із 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
заяви. Крім того, оскільки це булеві прапори, ви можете моделювати кожен сценарій як постійний і перевіряти його.