Типичная безопасная делегация без экземпляра - PullRequest
3 голосов
/ 13 июня 2011

У меня есть служебная подпрограмма:

filter(List<Criterion> criteria);

Есть ли хороший способ внутренне отправить вызов метода в безопасную реализацию определенной Criteria без участия instanceofи не загромождая API.

Я бы хотел что-то вроде следующего (что, естественно, не работает):

filter(List<Criterion> criteria) {
   for (Criterion c : criteria) {
       dispatch(c);
   }
 }

dispatch(FooCriterion c) {...}
dispatch(BarCriterion c) {...}

Ответы [ 4 ]

4 голосов
/ 13 июня 2011

Звучит так, будто вы хотите использовать шаблон посетителя .

Статья в Википедии содержит пример Java.

3 голосов
/ 13 июня 2011

Хотя это можно рассматривать как беспорядок, можно использовать что-то вроде шаблона Visitor (используя принцип двойной отправки):

public class Dispatcher {
    void dispatch(FooCriterion foo) { .. }
    void dispatch(BarCriterion bar) { .. }
}

class FooCriterion implements Criterion {
   void visit(Dispatcher d) {
      d.dispatch(this);
   }
}

Dispatcher d = new Dispatcher();
for (Criterion c : criteria) {
   c.visit(d);
}
0 голосов
/ 13 июня 2011
I have only this to suggest with some duplication.
private void filter(List<Criterion> criteria) 
{
 for(FooCriterion c : fetchFooCriterias(criteria))
 {
  dispatch(c);
 }
}
private List<FooCriterion> fetchFooCriterias(List<Criterion> criteria) 
{
 List<FooCriterion> fc = new ArrayList<FooCriterion>();
 for(Criterion c:criteria)
 {
  if(c instanceof BarCriterion)
  {
   fc.add((FooCriterion)c);
  }
 } 
 return fc;
}

Другим решением может быть использование следующих общих классов, но это может загромождать ваш код. import org.apache.commons.collections.Predicate; import org.apache.commons.collections.iterators.FilterIterator;

Попробуйте.

0 голосов
/ 13 июня 2011

Шаблон посетителя является предпочтительным решением, если вы хотите, чтобы один и только один экземпляр метода вызывался в соответствии с типом объекта.

Однако, если у вас есть C наследует, B наследует A, и вы хотите, чтобы ваши объектычтобы вызвать метод для их типа класса и всех унаследованных (например), вы должны использовать isAssignableFrom (...) .

Например, если ваш объект имеет тип B и вычтобы он вызывал dispatch(B obj) и dispatch(C obj), вам необходимо заключить эти вызовы соответственно в:

if (A.isAssignableFrom(obj.getClass())) { dispatchA(obj); }
if (B.isAssignableFrom(obj.getClass())) { dispatchB(obj); }
if (C.isAssignableFrom(obj.getClass())) { dispatchC(obj); }

Никогда не используйте instanceof, потому что в этом случае он не будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...