Generic EventDispatcher
От: Аноним  
Дата: 19.05.12 21:10
Оценка:
Всем привет. Застрял в одном месте, никак не знаю как решить проблему.
Общая суть.
Есть иерархия классов.


public abstract class A {
}

public class B extends A {
}

public class C extends A {
}

Собственно с какой-то реализацией, но это не важно, также использую Google пакет guava и eventBus.

Соствеено хочу написать дистпатчер, но чтобы он принемал события дженериками

Класс события.
public class CreateEvent<T extends A> {

}

Дистпатчер

public class Test {
    public void createEntity(CreateEvent<T extends A>) {
        //Создать объект определенного класса
    }
}

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

Спасибо
Re: Generic EventDispatcher
От: Аноним  
Дата: 19.05.12 21:46
Оценка:
Может быть, я иду не верным путем и так никто не делает? Не нужно широких ответов, просто куда копать и где посмотреть, либо может на какой нить класс в исходниках? Спасибо.
Re: Generic EventDispatcher
От: RomikT Германия  
Дата: 19.05.12 23:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Соствеено хочу написать дистпатчер, но чтобы он принемал события дженериками


В общем случае узнать тип генерик-параметра нельзя из-за type erasure. Конкретно в вашем случае можно использовать
Class<? extends A> realClass = ((ParameterizedType)event.getClass().getGenericSuperclass()).getActualTypeArguments()[0]
Но лично я бы не назвал такое решение хорошим.
Re[2]: Generic EventDispatcher
От: Аноним  
Дата: 20.05.12 08:00
Оценка:
Здравствуйте.

Тогда какое хорошее решение, для того чтобы отправлять сообщение на создание объекта. Я думал, как вариант при создании события, создавать и сам объект с конструктором по умолчанию, но как то не очень хочется создавать объект до того как событие будет выполняться.

2 вариант, для событий "создать" не использовать генерик, а создавать отдельные классы событий, но так растет и кол-во классов.
3 вариант, при создании события, указывать тип объекта в каком-нибудь поле, опять же выкидываем генерик для данного класса события.

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

Здравствуйте, RomikT, Вы писали:

RT>Здравствуйте, Аноним, Вы писали:


А>>Соствеено хочу написать дистпатчер, но чтобы он принемал события дженериками


RT>В общем случае узнать тип генерик-параметра нельзя из-за type erasure. Конкретно в вашем случае можно использовать

RT>
Class<? extends A> realClass = ((ParameterizedType)event.getClass().getGenericSuperclass()).getActualTypeArguments()[0]
Но лично я бы не назвал такое решение хорошим.
Re: Generic EventDispatcher
От: Baudolino  
Дата: 20.05.12 08:15
Оценка:
public class CreateEvent<T extends A> {
    private Class<T> targetType;
   
    public CreateEvent(Class<T> targetType) {
         this.targetType = targetType;
    }
   
    public Class<T> getTargetType() {
         return targetType;
    }

}

public class Test {
    public void createEntity(CreateEvent<T extends A> event) {
        try {
            T instance = event.getTargetType().newInstance();
        } catch (Exception e) {
            // TODO
        }
    }
}
Re[2]: Generic EventDispatcher
От: Аноним  
Дата: 20.05.12 08:18
Оценка:
Здравствуйте, видел такое решение, является ли оно "хорошем" в данном случае, так теперь, у меня еще может появится exception, плюс создание сорбытия будет таким CreateEvent<B>(B.class);

Здравствуйте, Baudolino, Вы писали:

B>
B>public class CreateEvent<T extends A> {
B>    private Class<T> targetType;
   
B>    public CreateEvent(Class<T> targetType) {
B>         this.targetType = targetType;
B>    }
   
B>    public Class<T> getTargetType() {
B>         return targetType;
B>    }

B>}

B>public class Test {
B>    public void createEntity(CreateEvent<T extends A> event) {
B>        try {
B>            T instance = event.getTargetType().newInstance();
B>        } catch (Exception e) {
B>            // TODO
B>        }
B>    }
B>}
B>
Re: Generic EventDispatcher
От: abch-98-ru Россия  
Дата: 20.05.12 09:32
Оценка:
class CreateEvent<T extends A> { // или интерфейс.
   T create();   
}
class Sender {
 public void send(){
  eventSender.send(new CreateEvent<B>(){ // или эту фабричность в мемберы класса, если параметров создания нет.
      @Override
      public B create() {
          return new B();
      }
  });
  eventSender.send(new CreateEvent<C>(){ // see above
      @Override
      public C create() {
          return new C();
      }
  });
 }
}

class Receiver{

    <T extends A> void onMessage(CreateEvent<T> event) { 
        T t = event.create();
        //...
    }
}
Re[3]: Generic EventDispatcher
От: Baudolino  
Дата: 20.05.12 10:54
Оценка:
А>Здравствуйте, видел такое решение, является ли оно "хорошем" в данном случае, так теперь, у меня еще может появится exception, плюс создание сорбытия будет таким CreateEvent<B>(B.class);
Решение является хорошим, если оно решает вашу задачу, и плохим, если оно задачу не решает. Более того, в большинстве случаев решение напрямую следует из формулировки задачи, и если вас что-то не устраивает в предлагаемых решениях, значит вы недостаточно хорошо сформулировали задачу. Простой вопрос: почему вас беспокоит исключение? Вопрос посложнее: а зачем вам вообще создавать объекты таким образом? Какую задачу вы в действительности решаете?
Re[4]: Generic EventDispatcher
От: Аноним  
Дата: 23.05.12 08:14
Оценка:
А>>Здравствуйте, видел такое решение, является ли оно "хорошем" в данном случае, так теперь, у меня еще может появится exception, плюс создание сорбытия будет таким CreateEvent<B>(B.class);
B>Решение является хорошим, если оно решает вашу задачу, и плохим, если оно задачу не решает.
Если решение не решает задачу — оно не плохое, а некорректное. Строго говоря — это не решение.

B>Более того, в большинстве случаев решение напрямую следует из формулировки задачи, и если вас что-то не устраивает в предлагаемых решениях, значит вы недостаточно хорошо сформулировали задачу.

Ты виноват, что не сказал, ты виноват, что не спросил. Что за детский сад?
Re: Generic EventDispatcher
От: zubr Россия  
Дата: 25.05.12 12:40
Оценка:
Здравствуйте, Аноним, Вы писали:

Если уж совсем не хочется писать код, то можно сделать так:
public BaseClass getNewInstance() {
   try {
      return this.getClass().newInstance();
   } catch (???) {
      return null;
   }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.