![]() |
|
||||||||||
|
|||||
|
Modus ponens
|
Вот недавно столкнулся с такой штукой... Знакомый попросил помочь разобраться с кодом. Описывать что там и как не буду, главное, там была загвоздка с использованием Delegate. Я как-то давно почитав описание этого класса, возможно, особо не вникая, решил, что это вобщем-то бесполезная штука. Т.как на сколько я понял - нужен он для того, чтобы переопределить this для вызываемой функции. Но если строить функции так, что они нигде не обращаются к this, а все объекты с которыми они работают передаются им в параметрах, то нет никакой необходимости в использовании Delegate...
Собственно, вопрос-просьба, если кому не лень... Объясните, мб, я не правильно понял назначение класса. Ну или по крайней мере приведите пример, где использование этого класса предпочтительно\необходимо. Потому что как ни крути, у меня получается просто, как минимум несколько "лишних" строчек кода, если я пытаюсь сделать что-то с использованием Delegate.
__________________
Hell is the possibility of sanity |
|
|||||
|
Я тоже не юзаю Delegate.
Но умные люди твердят, что это нужно для простоты понимая иерархии классов, для логического разделения методов между классами. Последний раз редактировалось miramax; 31.10.2006 в 19:40. |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
Delegate используется в силу того, что многие объекты во Flash 8 (и ниже) не являются вещателями, т.е. невозможно подписаться на события объекта.
Есть некий класс, который занимается обработкой данных, полученных из XML. Обработка — задача именно этого класса, а не объекта XML (как раз то, о чём пишет miramax). Поэтому, т.к. подписаться на onLoad нельзя, используется перенаправление вызова данного метода в метод нашего класса, т.е. как бы подписка на события. У меня есть класс AbstractXML, который является вещателем, вот как он выглядит: import mx.events.EventDispatcher;
/**
* @author Denis Kolyako
*/
class ru.etcs.data.AbstractXML extends XML {
private var __xml_url:String;
public var event:String = 'onXMLLoad';
public var errorEvent:String = 'onXMLLoadError';
public var idMap:Object;
private var dispatchEvent:Function;
public var addEventListener:Function;
public var removeEventListener:Function;
public function AbstractXML(xml_url:String) {
super("");
this.ignoreWhite = true;
EventDispatcher.initialize(this);
this.__xml_url = xml_url;
this.load(this.__xml_url);
}
private function onLoad(ok:Boolean):Void {
if (!ok || !this.loaded || this.status || this.getBytesTotal()<30) {
trace('XML loaded: '+this.loaded+', valid: '+this.status);
this.dispatchEvent({type:this.errorEvent});
return;
}
this.prepareData();
this.dispatchEvent({type:this.event});
}
private function prepareData():Void {
// For override
}
}
|
|
|||||
|
Modus ponens
|
2 __etc:
Я уже видел этот код в другом топе... там же я написал, каким образом решил бы проблему отслеживания загрузки ХМЛя, если бы я использовал кастомный класс, подкласс ХМЛя. Мой код вышел короче + не нужно было импортировать классы по умолчанию не включающиеся при публикации... Т.е. вопрос, по крайней мере для меня, по прежнему открыт. Не вижу в таком решении ни упрощения ни оптимизации. На лицо факт - конечная флешка в результате использования такого подхода просто немного вырастет в размерах (скорость работы думаю не изменится, с чего бы).
__________________
Hell is the possibility of sanity |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
А я вижу в таком решение упрощение и оптимизацию:
а) Я не создаю лишних ссылок и переменных б) Область видимости в классе остаётся всегда одной и той же в) Каждый класс занимается тем, чем ему положено и ничем иным Дело не в сокращении кода, а в исключении досадных ошибок. Я никогда не повторю оператор function внутри метода, потому что из-за этого могут возникнуть проблемы, вроде пропадания внешней переменной, не говоря уже о том, что будешь сбит другой областью видимости внутри функции. В AS3 тебе нужно будет подписывать на события, мой AbstractXML близок по духу к AS3 и у меня врядли возникнут сложности в работе с AS3. Впрочем, если вам удобно писать так, как вы пишите — пожалуйста. Это не более, чем просто рекомендации. Я не скажу, что прям уж так знаю все принципы ООП, но главный из них — минимальную связь между классами стараюсь соблюдать. Последний раз редактировалось etc; 01.11.2006 в 01:15. |
|
|||||
|
Modus ponens
|
В таком случае (чтобы не допустить ошибку) я лучше комент напишу... Затраты по времени ровно точно такие же, но на конечный результат не повлияет. Ну и меня нисколько не смущает то, что один и тот же класс будет и загружать и разбирать ХМЛ, как правило именно это и нужно, а не 2 класса, один для загрузки, второй для разборки. Более того, мне скорее даже нравится то, что не нужно плодить лишние сущности в виде многочисленных классов, в которых, на мой взгляд, как раз таки легче запутаться.
Кроме того, я бы не назвал ссылку\переменную лишней если она упрощает доступ к нужному свойству. В конце концов чем отличается переменная\ссылка в классе от практически такой же ссылки на листенер? Смысл-то самой операции нисколечки не меняется, просто в случае с Delegate нужно написать на пару строчек больше... Т.е. если я правильно понял, практической пользы в Delegate все таки нет? Исключительно "организационный момент"? Т.е. даже теоретически не может существовать случая когда бы его использование привело к лучшему результату (меньший объем кода \ большая производительность)? ЗЫ. Можно спать спокойно? =)
__________________
Hell is the possibility of sanity |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
Похоже, мне вас переубедить вообще не удастся.
Ссылка, которая определяется вне функции может вообще не существовать внутри того же onLoad! Это лишняя ссылка. Дело не в упрощении, а в возможной потери контроля над ситуацией. Если делать более менее правильно (слабые связи) — нужно делать класс, расширяющий XML и являющийся вещателем (в AS3 это так и есть). Далее, если всё же использование такого класса неприемлимо — Delegate, в этом случае потери логики и сваливания чужих функций в другой класс не происходит. А если писать так, как вы предлагаете: var classInstance:AnyClass = this;
this.anyXML.onLoad = function(success:Boolean):Void {
this.xmlDecl = ''; // Ага, а куда ссылается this? FDT даст по рукам сразу же
classInstance.onXMLLoad();
};
Я уже не говорю про какие-нибудь кнопки, которым нужно прописать обработчики onRelease, onPress… В общем, если не хотите использовать Delegate — не используйте, я же не заставляю ![]() А я же не буду создавать себе дополнительных сложностей в виде создания каких-то ссылок, непоняток с областью видимости и вообще, заниматься описанием методов одного класса в описании другого (когда этот метод по факту должен быть описан в данном классе, а не в каком-нибудь XML) — у меня других забот хватает. К тому же, бывают ситуации, где Delegate просто необходим (случай с XML — тривиальный, найду посложнее — покажу) и он является отличным инструментом. В AS3 он не нужен, все объекты (кроме некоторых, разумеется) являются наследниками EventDispatcher и можно просто подписаться на события. Если вам понадобиться переписать проект на AS3, то вам придёться переписывать весь код (даже хотя бы просто потому что он неприемлим в AS3, это в AS1 сплошь и везде так писали). В случае с Delegate — заменить одну строку. В случае уже использования класса-надстройки — или удалить класс и поменять везде на XML или же, если в этом классе есть доп. методы, убрать инициализацию диспетчером и объявление его методов. Всё, никаких проблем нет. Впрочем, не хотите — не пишите. Если для вас пользы нет, значит нет. |
|
|||||
|
Modus ponens
|
2 __etc:
И все-таки вы меня не поняли... Я не противник и не сторонник использования этого класса. Я просто не понимаю зачем он нужен. Пример в посте №7 ничего не объясняет... или я не понял, что он должен был бы объяснять... Я же не сравниваю неработающий код с работающим. Я сравниваю результат двух работающих кодов. Т.е. если я увижу, что Delegate в каком-то конкретном случае или сокращает время написания кода, или уменьшает итоговый вес файла, или увеличивает быстродействие - я с радостью буду его там использовать. Просто пока что я не видел случая когда бы с прагматических позиций использование Delegate было оправдано. Буду очень признателен, если вы покажете какой-нибудь пример, где именно с этих позиций использование Delegate дает плюсы.
__________________
Hell is the possibility of sanity |
|
|||||
|
Регистрация: Mar 2001
Адрес: msk
Сообщений: 1,416
|
Не читал, много букв.
Карочи, delegate правильно выставляет область видимости функции. Это ничем не лучше работает, просто корректнее. |
![]() |
![]() |
Часовой пояс GMT +4, время: 04:26. |
|
|
« Предыдущая тема | Следующая тема » |
|
|