Создание фильтров методов

В моем коде есть List<Person>. Атрибуты объектов в этом списке могут включать что-то вроде:

  • ID
  • Имя
  • Фамилия

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

i.e.:

switch typeOfSearch    
if 0, lookById()    
if 1, lookByIdAndName()  
if 2, lookByFirstName()

и так далее. На самом деле существует 7 различных типов.

Это дает мне один метод для каждого оператора. Это «хороший» способ сделать это? Есть ли способ использовать параметр или какой-то «фильтр»? Возможно, это не имеет значения, но я кодирую это на Java.


person Cody    schedule 05.07.2011    source источник


Ответы (4)


Вы можете сделать что-то более элегантное с картами и интерфейсами. Попробуйте это, например,

interface LookUp{
    lookUpBy(HttpRequest req);
}

Map<Integer, LookUp> map = new HashMap<Integer, LookUp>();

map.put(0, new LookUpById());
map.put(1, new LookUpByIdAndName());

...

в своем контроллере, тогда вы можете сделать

int type = Integer.parseInt(request.getParameter(type));
Person person = map.get(type).lookUpBy(request);

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

person Amir Raminfar    schedule 05.07.2011

Если хорошее означает «язык делает это за меня», нет.

Если хороший означает «читабельный», я бы определил в Person метод match (), который возвращает true, если объект соответствует вашим критериям поиска. Кроме того, вероятно, это хороший способ создать метод Criteria, в котором вы можете инкапсулировать критерии поиска (какие поля вы ищете и какое значение) и передать его для соответствия (критерии критериев).

person SJuan76    schedule 05.07.2011

Этот способ быстро становится неуправляемым, поскольку количество комбинаций быстро становится огромным. Создайте класс PersonFilter, имеющий все возможные параметры запроса, и посетите каждого человека в списке:

private class PersonFilter {
    private String id;
    private String firstName;
    private String lastName;

    // constructor omitted

    public boolean accept(Person p) {
        if (this.id != null && !this.id.equals(p.getId()) {
            return false;
        }
        if (this.firstName != null && !this.firstName.equals(p.getFirstName()) {
            return false;
        }
        if (this.lastName != null && !this.lastName.equals(p.getLastName()) {
            return false;
        }

        return true;
    }
}

Фильтрация теперь осуществляется

public List<Person> filter(List<Person> list, PersonFilter filter) {
    List<Person> result = new ArrayList<Person>();
    for (Person p : list) {
        if (filter.accept(p) {
            result.add(p);
        }
    }
    return result;
}
person JB Nizet    schedule 05.07.2011

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

person Michael J. Lee    schedule 05.07.2011