Внедрение синтаксического анализатора зависит от условий

#java #spring-boot

Вопрос:

Я ищу лучшее решение для организации кода в проекте. Итак, у меня есть большая строка позиции, которая поступает из внешнего сервиса. Это выглядит примерно так:

 "2020-01-03     some    values  13DHELLO   andmore  values"
 

Также с этой строкой, которую нужно разобрать, у меня разные свойства. Зависит от свойства, которое мне нужно ввести в конкретную реализацию синтаксического анализатора и передать туда строку для отображения конкретной модели. Каждая реализация синтаксического анализатора возвращает другую модель.
Прямо сейчас я реализовал некоторую логику, такую как:

 switch (response.getParameter()) {
        case FIRST_PARAMETER:
            switch (response.getAdditionalInfo()) {
                case NESTED_FIRST_PARAMETER:
                    return new FirstParser(response.getData()).parse();
                case NESTED_SECOND_PARAMETER:
                    return new SecondParser(response.getData()).parse();
                case NESTED_THIRD_PARAMETER:
                    return new ThirdParser(response.getData()).parse();
                default:
                    break;
            }
        case SECOND_PARAMETER:
            return new SecondParameterParser(response.getData()).parse();
        default:
            break;
}
 

Это выглядит очень страшно и трудно растянуть. Я думаю о том, как или как сделать это лучше. Возможно, получить хэш-карту и получить бобовую реализацию синтаксического анализатора зависит от значения перечисления. Тем не менее я не знаю, что делать с вложенными случаями.
Надеюсь, вы сможете помочь мне найти шаблон для решения этой задачи и улучшить код.

Ответ №1:

Что ж, предоставление какого-либо хранилища (простым может быть карта) было бы хорошим началом. Таким образом, вы можете вернуть фабрику синтаксического анализа, например, a FirstParserFactory , которая создает новый FirstParser из ответа.

Упрощенный пример с большим количеством проверок и отсутствием другого кода (я оставлю это вам 🙂 ):

Фабрика

 interface ParserFactory {
  Parser createParser(Response resp);
}

class FirstParserFactory implements ParserFactory  {
  public Parser createParser(Response resp) {
    return new FirstParser(resp.getData());
  }
}
 

Использование

 Map<String, ParserFactory> repository = ... //build

respository.get(response.getParameter()).createParser(response).parse();
 

Вложенные случаи могут обрабатываться вложенной фабрикой, например, как это:

 class NestedParserFactory implements ParserFactory {
  Map<String, ParserFactory> nestedFactories = ...;

  public Parser createParser(Response resp) {
    ParserFactory nestedFactory = nestedFactories.get(resp.getAdditionalInfo());
    if( nestedFactory == null ) {
      return null; //or handle in any other appropriate way
    }

    return nestedFactory.createParser(response);
  }  
}