Как можно удалить условные выражения при добавлении общей ответственности к классу? - PullRequest
1 голос
/ 29 апреля 2020

Я создаю механизм проверки. Существуют общие правила, которые я объединил в методе stati c родительского интерфейса.

    public interface EmployeeValidator {
        Predicate<Employee> build(Employee employee);

        static Predicate<Employee> getCommonRules(Employee employee) {
            return validateAge().and(validateGenger());
        }

        private static Predicate<Employee> validateAge() {
            ...
        }

        private static Predicate<Employee> validateGenger() {
            ...
        }
    }

Теперь класс, реализующий этот интерфейс, добавит в него больше правил проверки. Будет несколько реализаций EmployeeValidator

    class BackOfficeStaffValidator implements EmployeeValidator {

        @Override
        public Predicate<Employee> build(Employee employee) {
            return EmployeeValidator.getCommonRules(employee).and(validationsOnDirectReports());
        }

        private Predicate<Employee> validationsOnDirectReports() {
            ...
        }
    }

Но проблема с этим подходом у клиента. Мне нужны условные операторы или переключение регистра, чтобы выбрать правильную реализацию.

    Employee employee = ...;

    if(employee.staffType() == StaffType.TECHNICAL) {
        Predicate<Employee> validator = new TechnicalStaffValidator().build(employee);
    } else if(employee.staffType() == StaffType.BACK_OFFICE) {
        Predicate<Employee> validator = new BackOfficeStaffValidator().build(employee);
    }

Есть ли способ улучшить мой текущий дизайн? Если этот подход не движется в правильном направлении, не стесняйтесь предложить альтернативный подход.

1 Ответ

1 голос
/ 29 апреля 2020

Вы можете добавить метод наподобие isReponsibleFor (StaffType) в интерфейс EmployeeValidator. Теперь каждый валидатор может проверить, является ли он ответом для данного типа.

Добавьте все свои валидаторы в список и выполните итерации по списку валидаторов. Если ваш валидатор отвечает за данный тип, вызовите метод сборки. Вы также можете добавить проверки, так что для каждого типа есть только один валидатор и т. Д.

List<EmployeeValidator> validators = getListOfValidators();

for (EmployeeValidator validator : validators) {
   if (validator.isReponsibleFor(employee.staffType()) {
      Predicate<Employee> validator = validator.build(employee);
      // uses the first validator only
      break;
   }
}
...