Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > Делегирование при помощи java.lang.reflect.Method


Автор: C4Grey 31.3.2012, 00:35
Приветствую
Есть самописный мультипоточный сервер на сокетх. Каждый сокет обернут в обработчик(наследник Thread), который читает сообщения, обрабатывает исключения + еще пару функций. Сообщения - сериализируемые классы, все имеют целочисельное поле DataType(наследуется от базового класса собщений). К обработчику прикреплен класс MessageProcessor, который описывает логику обработки сообщения(отправить список игроков, добавить пользователя в комнату, переслать сообщение всем игрокам, и т.п.). Выбор метода обработки происходит по switch (AMessage.DataType) - в зависимости от соответствия DataType определенной константе выполняем некую функцию класса MessageProcessor. С Java работаю не очень давно, недавно узнал что в ней есть возможность создания методов-делегатов. Стало интересно, какой метод будет быстрее работать: switch в цикле чтения, или альтернатива - в конструкторе MessageProcessor(и наследников) формировать массив делегатов и дергать их по константе. Как-то так:

Код

protected void AddMethod(String AName, int AID) throws NoSuchMethodException, SecurityException
{
    Method vMethod = FThisClass.getMethod(AName, FMessageClass);
    FMethods[AID] = vMethod;    
}

и при чтении вызываем нужный метод:
Код

FMethods[AMessage.DataType].invoke(this, AMessage);

Примеры упрощенные, без проверок на существование метода(в случае, если пришел неизвестный ID) и т.п.

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

Автор: kosmonaFFFt 31.3.2012, 16:47
Насколько я знаю, reflection довольно медленный, лучше было бы сделать один интерфейс для обработчиков, и каждый обработчик сделать как его реализацию, а в коллекции уже хранить ссылки на объекты обработчиков...

Автор: C4Grey 1.4.2012, 00:37
Спасибо за ответ
Касательно распределения обработчиков по классам - думал об этом, даже частично реализовал, но большинство методов - строчек 10 кода, заводить ради них по классу...ну, как-то странно smile . Касательно reflection - встречал несколько статей, где её тормознутость в самом начале рассматривается как аксиома, а дальше зачем-то эту аксиому доказывают, замеряя скорость выполнения getMethod, getConstructor и т.п. Меня интересует конкретно invoke с уже имеющейся ссылкой, подождать пару лишних секунд при коннекте не проблематично(можно было бы сделать статический класс-утилиту для обработки и выполянть поиск методов один раз, но манипуляции с потоками, семафорами, синхронизациями и прочими мультипоточными хитростями, являющимися для Java нормой, для меня внове - как-то удалось наладить существующую систему, пока не особо хочу менять структуру). 
P.S.
Пока что самой полезной для меня оказалась эта статья: http://habrahabr.ru/post/69552/ . Если исходить из представленных в ней статистических данных(хотя и не совсме корректно, на мой взгляд, собранных) то invoke осуществляется приблизительно в 100 раз медленнее прямого вызова. Думаю что полный ответ на свой вопрос получу только после собственного тестирования smile 

Автор: COVD 1.4.2012, 18:25
Цитата

строчек 10 кода, заводить ради них по классу...ну, как-то странно 

Отнюдь. Это просто и наглядно. Эти классы, если они небольшие, удобно создавать как анонимные (реализации интерфейса), т.е. не хранить каждый класс в отдельном файле.

Код

public interface DoIt {
   void doSomething(int i, double x);
}
private DoIt[] processors = new DoIt[256];

int id = 0;
processors[id] = new  DoIt (){
     void doSomething(int i, double x){
         // code for id = 0
     }
};
id = 1;
processors[id] = new  DoIt (){
     void doSomething(int i, double x){
         // code for id = 1     }
};
...

Автор: C4Grey 2.4.2012, 21:25
2COVD
Спасибо за совет, действительно разумная альтернатива. Был не прав, упершись в модель "один класс - один модуль/файл".

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)