#algorithm #oop #design-patterns #data-structures
#алгоритм #ооп #дизайн-шаблоны #структуры данных
Вопрос:
У меня есть метод класса, который реализует логику, основанную на правилах. Структура выглядит следующим образом:
sub process {
# declarations etc
# other code
# core logic:
if($conditions->{size} == $item_size) {
#do something here as it matches the rule based on size
return $resu<
}
if($conditions->{area} == $item_area_dispatch) {
#do something that matches the area criteria
return $resu<
}
if($conditions->{country} == $item_country) {
#do something that matches the country criteria
return $resu<
}
}
В принципе, существует ряд операторов if / else, которые проверяют, применяются ли определенные условия, и выполняют соответствующую логику.
Последовательность if / elses сверху вниз является наиболее специфичным критерием для наиболее общих, которые применяются
, и если правило не применяется, ничего не делайте.
Это работает, но порядок зависит от if / else, и всякий раз, когда я хочу добавить новое правило, я добавляю новое if / else в «правильное» место.
Так что это не идеальное решение. Мне интересно, каков был бы наилучший способ реструктурировать мой код для этого?
Комментарии:
1. Это может быть лучше подходит для программистов
2. ооп? очевидный выбор — хранить правила как объекты.
Ответ №1:
Вы не указываете какой-либо язык, поэтому мой ответ будет в основном связан с C / Java, но я думаю, что любой другой язык ооп должен предоставлять те же функции. Вы должны инкапсулировать свой критерий внутри объекта. Что-то вроде:
enum Priority {
HIGHEST = 0,
HIGHER = 1,
...
LOWEST = 9
}
class Criterion {
public final Priority priority;
public abstract boolean evaluate(YourObject object);
Criterion(Priority priority) { this.priority = priority; }
}
class SearchCriteria {
List<Criterion>[] criteria = new ArrayList<Criterion>[10];
void addCriterion(Criterion criterion) {
criteria[criterion.priority].add(criterion;
}
boolean evaluate(YourObject object) {
for (List<Criterion> list : criteria)
for (Criterion c : list)
if (c.evaluate(object))
return true;
return false;
}
}
class CountryCriterion extends Criterion {
public final Country country;
CountryCriterion(Country country) { super(Priority.HIGHER); this.country = country; }
boolean evaluate(YourObject object) { return object.country.equals(country); }
}
Теперь, это просто для того, чтобы дать вам пример того, как это может работать, вы могли бы выбрать другой способ хранения приоритетов или что-то еще, чтобы иметь возможность передавать параметры текущим критериям.
Комментарии:
1. 1 Я думал о чем-то подобном, но был слишком ленив, чтобы записать это. Может сделать
Criterion
сравнениеPriority
и поместить их в упорядоченный список или очередь приоритетов.