обработчик цепочки ответственности с обобщением java - PullRequest
5 голосов
/ 27 ноября 2010

Я использую шаблон-цепочку ответственности в Java. Цепочка в целом представляет собой запрос на объекты определенных типов. Каждый «Обработчик» в цепочке отвечает за обработку запрошенных единиц 1 типа. Все запросы обрабатываются практически одинаково, поэтому я попытался сделать класс «Handler» универсальным. Поэтому в классе Handle мне нужен такой метод (сама обработка упрощена, потому что это только запутало бы мою проблему):

public class Handler<T>{
   int required;
   Handler<?> next;

   public void handle(Object O){
      if(o instanceof T){
         required --;
      }else{
         next.handle(o);
      }
   }
}

Проблема в том, что такой экземпляр невозможен. Потому что тип T явно не хранится во время выполнения (или это то, что я понял во время моего исследования в Интернете). Поэтому мой вопрос: что является лучшей альтернативой?

Ответы [ 4 ]

2 голосов
/ 27 ноября 2010

Реализуйте обработчики, используя обобщенные значения, используя параметр конструктора для определения класса, поддерживаемого обработчиком:

public class Handler<T> {
    private int required;
    private Handler<?> next;
    private Class<? extends T> c;

    public Handler(Class<? extends T> c) {
        this.c = c;
    }

    public void handle(Object o) {
        if (c.isInstance(o)) {
            required--;
        } else {
            next.handle(o);
        }
    }

    // ...
}    
1 голос
/ 27 ноября 2010

Похоже, что вы вообще не используете цепочку, если только у вас нет случаев, когда и базовый, и подклассы запускают события. Если это, если часть не применяется, вы можете сделать что-то вроде

Map<Class, Handler> handlers = //...initialize however

и в корневом обработчике:

public void handle(Object o) {
 handlers.get(o.getClass()).handle(o);
}
1 голос
/ 27 ноября 2010

Это было бы ужасно, но вы могли бы попробовать это:

public abstract class Handler {
   int required;
   Handler next;

   public void handle(Object o){
      if(getMyClass().isInstance(o)){
         required --;
      }else{
         next.handle(o);
      }
   }

   protected abstract Class getMyClass();
}
0 голосов
/ 27 ноября 2010

Не имеет смысла иметь обработчик, использующий дженерики, если вы вызываете handle для каждого объекта. Либо вы создаете экземпляр обработчика для типа, подобного этому:

public class Handler<T>{
   int required;
   Handler<?> next;

   public void handle(T O){
     ...
   }
}

или вы определяете обработчик абстрактного класса и позволяете конкретному подклассу обрабатывать определенный тип или просто передавать событие в цепочку. Также используя

if( x.isInstance(o)) {...}

действительно антипаттерн, и вы можете нарушать правила ООП.

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