2015-01-26 2 views
2

Я пишу поисковый синтаксический анализатор. Существует входной запрос поиска (String), который необходимо преобразовать в отдельный объект условия. ?Шаблон проектирования для создания нескольких объектов одного типа

Например,/perons/д = возраст> 50 & Имя: Майк

Этот запрос будет переводить на два объекта состояния. 1.GreaterThanCondition (String поле, INT значение) 2.LikeCondition (String поле, значение String)

У меня есть 14 таких условий объекты, которые реализуют интерфейс Condition.

Во время выполнения я разбираю условие строки из запроса (например, «возраст> 50»), и мне нужно разработать алгоритм, который бы эффективно преобразовал это условие в соответствующий объект (например, GreaterThanCondition) эффективно.

Вот один алгоритм, о котором я думаю: создайте ConditionFactory. Этот ConditionFactory будет принимать эту строку («возраст> 50») и перебирать существующие 14 фабрик в определенном порядке (по одной фабрике для каждого условия), чтобы соответствовать, если регулярное выражение, определенное на заводе (например, регулярное выражение для GreaterThanConditionFactory может быть [ a-zA-Z0-9] +> + [0-9] +. Основываясь на регулярном выражении, GreaterThanConditionFactory может идентифицировать поле (возраст) и значение (50) из условия и создать объект GreaterThanConditionObject.

При таком подходе, Мне нужно создать 15 заводов и 14 состояния объекта. Я не уверен, что создание многих заводов является хорошим решением. Просьба предложить.

+0

Зачем вам 1 завод на каждое условие? Кроме того, похоже, что вы создали Chain of Responsibility Factory ... который не похож на * ужасную идею. –

+0

@ Elliott Если я поместил все на свою единственную фабрику, в моем ConditionFactory будет слишком много логики и слишком много, если бы были другие условия. Например, код будет выглядеть так: if ("age> 50"). Match (GreaterThanConditionRegex) {найти поле и значение; создать объект GreaterThanConditon; } else {..} –

+0

Вместо одной фабрики рассмотрите [Builder] (http://en.wikipedia.org/wiki/Builder_pattern#Definition). Ваша логика должна куда-то идти. –

ответ

0

Вы можете использовать очень простой recursive descent parser, который использует CharacterIterator и builder. Это было бы более читаемым, это было бы быстрее, чем проверка на 14 регулярных выражений и поддержка нескольких условий запроса.

public class QueryParser { 
    CharacterIterator iterator; 
    QueryBuilder queryBuilder; 
    QueryConditionBuilder queryConditionBuilder; 

    public Query parse(String text) { 
    iterator = new StringCharacterIterator(text); 
    queryBuilder = new QueryBuilder(); 
    while (hasNext()) { 
     queryConditionBuilder = new QueryConditionBuilder(); 
     conditionSeparator(); 
     queryCondition(); 
     queryBuilder.withCondition(queryConditionBuilder.getQueryCondition()); 
    } 
    return queryBuilder.getQuery(); 
    } 

    public void conditionSeparator() { 
    // if the next character is an &, then advance the iterator 
    } 

    public void parseQueryCondition() { 
    key(); 
    operator(); 
    value(); 
    } 

    public void parseKey() { 
    // ... keep reading until the next character is not alphabetic 
    queryConditionBuilder.withKey(key); 
    } 

    public void parseOperator() { 
    // ... could be as simple as a one character check 
    queryConditionBuilder.withOperator(operator); 
    } 

    public void parseValue() { 
    // ... probably a number, so just read until the next character is not a digit or you reach the end of a string 
    queryConditionBuilder.withValue(value); 
    } 

    public Character peek() { 
    // delegate to character iterator 
    } 

    public Character next() { 
    // delegate to character iterator 
    } 

    public boolean hasNext() { 
    // delegate to character iterator 
    } 
} 
Смежные вопросы