Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 21.03.2011, 14:22
arkadattx вне форума Посмотреть профиль Отправить личное сообщение для arkadattx Найти все сообщения от arkadattx
  № 1  
Ответить с цитированием
arkadattx

Регистрация: Apr 2010
Сообщений: 219
По умолчанию Адекватное количество обработчиков

Просьба к флеш-общественности разрешить спор.
Ситуация: есть некий интерфейс (кнопочки всякие, а не Interface), при клике (наведении и пр.) на каждую из них необходимо выполнять какие-то действия, часто схожие между собой.
Суть спора. Я склонен считать, что на каждую такую кнопку необходимо вешать свой слушатель с обработчиком (в результате будет создано несколько методов). Мой оппонент предлагает использовать один слушатель на контейнере, внутри которого определять тип объекта, по которому клацнули и затем switch-case-ом по имени определять необходимые действия (т.е. всего один метод).
Вот пример:
Код AS3:
private function onMouseEvent(e:MouseEvent):void
{
	if (e.target is ISkinButton)
	{
		switch (e.target.name)
		{
			case "closeButton":
			case "exitButton":
			exit();
			break;
			case "plusButton":
			text(1);
			break;
			case "minusButton":
			test( -1);
			break;
		}
	}
}
Кто прав и почему?


Последний раз редактировалось arkadattx; 21.03.2011 в 14:26.
Старый 21.03.2011, 14:38
Александр Мостовой вне форума Посмотреть профиль Отправить личное сообщение для Александр Мостовой Посетить домашнюю страницу Александр Мостовой Найти все сообщения от Александр Мостовой
  № 2  
Ответить с цитированием
Александр Мостовой
 
Аватар для Александр Мостовой

Регистрация: Sep 2001
Адрес: Харьков
Сообщений: 305
Отправить сообщение для Александр Мостовой с помощью ICQ Отправить сообщение для Александр Мостовой с помощью Skype™
Мне удобно для каждой кнопочки создавать отдельный класс, который она наследуют от общего, оверрайдив обработчик для каждой, т.е. писать все это внутри класса кнопки. Удобно тем, что неважно знать где находится кнопка, можем кинуть ее в любой контейнер
__________________
...

Старый 21.03.2011, 15:04
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 3  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
За свитч-кейс убивать сразу, это заразно. Ято Ява-оптимизаторы такое любят, т.как в ней написать обработчик события - это цельный класс с методами и имплементациями и т.п. Во флеше обработчик - это всего одна функция! А свитч искажает логику программы, усложняет тестирование и вообще чтение, при том, что если и есть какая-то разница в производительности - она на столько минимальна, что вы ее никогда не увидите. И шансы за то, что в том же свитче в итоге будут сделаны лишние телодвижения, которые эту самую производительность снова просадят.
Т.е. сравните:
Код AS3:
function close_clickHandler(event:Event):void {}
function open_clickHandler(event:Event):void {}
// и
function clickHandler(event:Event):void
{
	switch (event.target)
	{
		case foo:
			break;
		case bar:
			break;
		default: trace("???");
	}
}
Т.е. в первом случае логика работает железно: нажали на "close" -> попали в обработчик "close". В то время как во втором случае: нажали на "close" -> попали в неизвесный обработчик, где усилием воли мы разгадали, что же нужно делать. Но в последнем случае имеем еще одно логическое несоответсвие - у написаной нами фунции есть избыточный фунционал. А именно default кейс. А нужен он исходя из ТЗ? - нет. Помогает ли он функции работать лучше? - нет, даже наоборот, оставляет простор для ошибок и последующего неправильного ее использования. Кроме того, эта функция может "вдруг" быть переопределена в классе наследнике. И класс-наследник "вдруг" будет зависеть от ее результатов, но его абсолютно не интересует, что происходит с кнопкой open, а возможно и нет у него такой - а в этой функции она есть! И в тот момент, когда класс-наследник случайно удалит foo, то оба кейса будут указывать на один и тот же объект (null), что почти наверняка создаст аварийную ситуацию, которую, кроме всего прочего тяжело выявить.
Вот так вот.
__________________
Hell is the possibility of sanity

Старый 21.03.2011, 15:25
Stargazer вне форума Посмотреть профиль Отправить личное сообщение для Stargazer Найти все сообщения от Stargazer
  № 4  
Ответить с цитированием
Stargazer

Регистрация: Nov 2008
Сообщений: 528
Голосую против case-ов.
Это искусственная конструкция, возникающая потому что кому-то лень написать 2 лишних строки (хотя отдельные функции и быстрее и проще написать и проще потом читать).

Старый 21.03.2011, 15:54
arkadattx вне форума Посмотреть профиль Отправить личное сообщение для arkadattx Найти все сообщения от arkadattx
  № 5  
Ответить с цитированием
arkadattx

Регистрация: Apr 2010
Сообщений: 219
wvxvw, спасибо за объяснения.
В данном проекте подобный функционал никогда не будет переопределяться. default отсутствует. То что "попали в неизвестный обработчик" (я так понимаю что речь идет скорее о неизвестной части обработчика) - можно заменить конструкцией типа
Код AS3:
if(name==ThisClass.CONSTANT_NAME){
//*****
return;
}
Таким образом мы уменьшаем количество возможных ошибок и гарантированном попадем в нужный участок обработчика.
При таком условии есть у такого подхода еще недостатки?
Александр Мостовой, Stargazer, спасибо за мнение, но хотелось бы больше конкретики и объективизма. Личные предпочтения каждого - дело такое... Не стабильны как мода.

Старый 21.03.2011, 16:05
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 6  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Для начала, default не может отсутствовать, то, что вы его не написали, еще на значит, что его нет. Он есть всегда, хотите вы того или нет. А за возвраты из функции в непредвиденных местах можно, если еще шевелится, контрольный выстрел сделать - хуже не будет.
Нет, еще раз, в switch'e вы делаете предположение, что event.current таргет а) существует, б) не равен нулю. При том, что оба эти предположения могут не выполнится. Т.е. вы предлагаете 100% работающий вариант заменить 99% работающим вариантом, аргументируя это чем? Улучшением производительности? На микрон? А если компилятор окажется в силах (в будущем) заинлайнить код обработчика? Так вы только просадите производительность вашим свитчем, т.как его будет труднее разделить на части и заинлайнить в разные места по частям. Но это уже гости из будущего
С другой стороны, написав свитч, вы усложните себе последующую разработку и сопровождение - опять же, такие жертвы только ради того, чтобы выиграть миллисекунду на вызове 1000 обработчиков?
__________________
Hell is the possibility of sanity

Старый 21.03.2011, 16:13
kyzi007 вне форума Посмотреть профиль Отправить личное сообщение для kyzi007 Найти все сообщения от kyzi007
  № 7  
Ответить с цитированием
kyzi007

Регистрация: Nov 2008
Сообщений: 78
С автогенерацией кода конечно на каждую кнопку отдельный слушатель намного удобнее / красивее, только имена придумать

По мне все зависит от архитектуры.

Код AS3:
case "closeButton":
case "exitButton":
exit();
А вот тут я бы сделала класс кнопок который диспатчил бы события - не клик, а свои (AppControlEvent), и диспатчил их в какой нибуть глобальный контейнер и такие -же события диспатчила бы по нажатию кнопок на клаве/прочих действий. Но это личные вкусы сформировавшиеся под давлением большого количества разнообразных контроллов в одном приложении которые валяются в разных парентах.

Старый 21.03.2011, 17:18
Stargazer вне форума Посмотреть профиль Отправить личное сообщение для Stargazer Найти все сообщения от Stargazer
  № 8  
Ответить с цитированием
Stargazer

Регистрация: Nov 2008
Сообщений: 528
Цитата:
Сообщение от arkadattx Посмотреть сообщение
Александр Мостовой, Stargazer, спасибо за мнение, но хотелось бы больше конкретики и объективизма.
Я уже выдал максимум конкретики: общий для всех обработчик - это искусственная конструкция. Для неё нет никаких причин, кроме лени разработчика написать несколько лишних строк.

Могу попытаться поподробнее.
Зачем вообще пишутся функции (а также объекты, классы и т.д.)?
Чтобы реализовать в них какой-то алгоритм и далее работать с этим алгоритмом как с некоей логической сущностью. Хорошие программы получаются только тогда, когда программист придерживается принципа, что классы, функции и т.д. не должны быть натулены как попало - а должны быть, по возможности, структурированы и разделены друг от друга. Чем меньше взаимосвязей тянется от одной логической единицы к остальным - тем это лучше. Ну и т.д. Не буду напоминать уж совсем очевидные вещи. Мораль вкратце: связи должны, по возможности, расходиться ровными аккуратными линиями, а не путаться клубками.

Вернёмся к вашей ситуации.
Совершенно классическая ситуация "событие-обработчик". Событие - это один элемент. Обработчик - это другой элемент. Логика подсказывает, что самым логичным будет просто напрямую связать один элемент с другим, ведь больше ничего и не нужно? Таким образом, связи в программе будут простыми и легко читаемыми: closeButtonClickHandler, settingsButtonClickHandler, ... и т.д. Всё просто и чётко. Мне нужно только ткнуть на имя функции в outline в FD и работать. Да и просто беглый взгляд по outline помогает тут же определить, чем занимается данный класс.

Вы же для чего-то хотите ввести дополнительный элемент, с целью сперва обобщить те вещи, у которых нет ничего общего (!), а потом разгородить всё обратно при помощи case. То есть вы выполняете 2 противоположных действия - ради чего? Назовите хоть 1 архитектурный плюс данного решения (аргумент "мне лень написать лишний раз addEventListener" не принимается).

В архитектуре мы видим очевидный минус: этот убер-обработчик имеет слишком ниточек, тянущихся к другим элементам системы. Если вы хотите добавить новый обработчик - вместо того, чтобы прописать ещё 1 функцию и сохранить код в чистоте - вы будете добавлять новый case с новым алгоритмом и каждый следующий case будет смотреться ещё более невыносимо, чем предыдущий, число ниточек будет расти и в итоге ваш обработчик окончательно превратится в помойку (чем он и был с самого начала, на самом деле). И вообще, если в case выполняется более 2 команд - то всё равно нужно делать отдельную функцию. При таком подходе вообще неясно на чём вы сэкономили.

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

Резюмируем:
-: логически не обосновано
-: читать неудобно
-: делает систему менее гибкой

+: ???


Последний раз редактировалось Stargazer; 21.03.2011 в 17:37.
Старый 21.03.2011, 20:56
carrotoff вне форума Посмотреть профиль Отправить личное сообщение для carrotoff Найти все сообщения от carrotoff
  № 9  
Ответить с цитированием
carrotoff
 
Аватар для carrotoff

Регистрация: May 2010
Сообщений: 543
Думаю не стоит использовать кейсы, ибо код становится нагроможденным и нечитабельным.
Особенно, в том случае если обработчики для ваших кейсов будут представлять собой не одну строку, как в примере (exit(), text(1), test(-1)), а целую конструкцию, и получится просто жесть типа

Код AS3:
private function onMouseEvent(e:MouseEvent):void
{
	if (e.target is ISkinButton)
	{
		switch (e.target.name)
		{
			case "closeButton":
			case "exitButton":
			function(){
                          if(a == b){
                             while(x < arr.length){
                             // .........
                             }
                          }
                        }
			break;
			case "plusButton":
			text(1);
			break;
			case "minusButton":
			test( -1);
			break;
		}
	}
}
Ну можно усложнять и усложнять..

Старый 21.03.2011, 21:38
Psycho Tiger вне форума Посмотреть профиль Отправить личное сообщение для Psycho Tiger Найти все сообщения от Psycho Tiger
  № 10  
Ответить с цитированием
Psycho Tiger
 
Аватар для Psycho Tiger

блогер
Регистрация: Jun 2005
Адрес: Господи пожалуйста не Новосибирск
Сообщений: 6,598
Записей в блоге: 17
Ранее ратовал за switch/case. Ныне вдохновившись речами wxvxw и собственным опытом ратую против них в подобных конструкциях.

Создать новую тему Ответ Часовой пояс GMT +4, время: 12:06.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 12:06.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.