Как насчет создания абстрактного базового класса для обработки сравнений правил:
abstract class PrioritizedRule<T> implements Rule<T>, Comparable<PrioritizedRule<T>>{
public int compareTo(PrioritizedRule<T> other){
//Implement something that compares rule priorities here.
//This will probably require support from the constructor, which-
//since this is abstract- must be Protected.
Оттуда ваш PrioritizedValidator (для которого требуется PrioritizedRule) будет сортировать () свою коллекцию в начале Validate (если его коллекция правил была изменена с момента последней проверки; это подходящее время для сортировки коллекции, так как мы не не нужно повторять сортировку при каждой модификации, если есть последовательные модификации, или делать сортировку, если нам это не нужно), и цикл Validate должен начинаться раньше, если его список сообщений об ошибках не пуст во время перехода между приоритетами правил:
public List<ErrorMessage> validate(T value) {
if(ruleSetModified){
//be careful: validate becomes unsafe for multithreading here, even if you
//aren't modifying the ruleset; if this is a problem, implement locking
//inside here. Multiple threads may try to sort the collection, but not
//simultaneously. Usually, the set won't be modified, so locking before
//the test is much, much slower. Synchronizing the method is safest,
//but carries a tremendous performance penalty
Collections.sort(rule);
ruleSetModified = false;
}
List <ErrorMessage> errors = new ArrayList<String>();
PrioritizedRule prev = null;
for (PrioritizedRule<? super T> rule : tests) {
if(prev != null && prev.compareTo(rule) != 0 && !errors.isEmpty()){
return errors;
}
errors.addAll(rule.check(value));
prev = rule;
}
return errors;
}
Я не уверен, что вы подразумеваете под "... без добавления механизма правил", но определение правил сортировки себя, вероятно, является наиболее изящным подходом. Однако будьте осторожны - любые два PrioritizedRule должны быть сопоставимы друг с другом, поэтому я рекомендую, чтобы PrioritizedRule была абстрактной базой, а не интерфейсом, потому что именно здесь должна существовать реализация CompareTo для согласованности. Ваш метод CompareTo не обязательно должен соответствовать «Равным», если только вы не попытаетесь сохранить свою коллекцию в отсортированном наборе, который никогда не может хорошо закончиться (PrioritizedRule не может знать достаточно, чтобы привести себя в соответствие с «Равными»!), Поэтому не пытайтесь .
В качестве альтернативы, внедрите Comparator>, но опять же, ваш интерфейс правила должен быть изменен, чтобы предоставить достаточно информации для сортировки.