为了保障原创作者在本站发表文章的利益, 并维护本站原创的精神, 特声明: RIAShanghai对有以下任何情况之一的文章将不通知作者并直接进行快意删除:
- 非原创, 或者原创但一文多发;
- 各种形式的广告与吹擂;
- 不符合本站文章格式.
欢迎各位读者监督. 谢谢合作. 另: 作为Adobe正式的UG, 我们将把Adobe不定期分发的软件,书籍及各种纪念品赠送给发文活跃的作者, 共同进步.
Flex's event mechanism is powerful and prompts loose coupling. However, there are times you should not over use it for the sake of simplicity and performance.
Use fixed function call if components are tightly coupled
For example, we have a class called UIUnit and UIGroup. A UIUnit belongs to one UIGroup. One requirement for UIGroup is to display a 'save' button whenever there is an input change in any UIUnit.
Version 1 - Using the event mechanism:
class UIGroup {
var units:ArrayCollection;
public function UIGroup(units_:ArrayCollection) {
this.units = units_;
for(var i:int = 0; i < units.length; i++) {
(units.getItemAt(i) as UIUnit).addEventListener("changed", onChanged);
}
}
public function onChanged(event:Event):void {
// display the 'save' button if it has not been shown yet.
}
}
class UIUnit extends EventDispatcher {
function onTextInput() { // called when there is input change on UI
dispatch(new ChangeEvent());
}
}It works. However, it requires a lot of resources. For example, if there are 100 UIUnits in the group. Each UIUnit needs a hash map object to store all listeners and a ChangeEvent object will be generated for each text input change. Let's suppose each UIUnit generates 5 such events. So basically the overhead for this event dispatching are 100 hash map objects + 500 event objects. Now, let's see version 2.
class UIGroup {
var units:ArrayCollection;
public function UIGroup(units_:ArrayCollection) {
this.units = units_;
for(var i:int = 0; i < units.length; i++) {
(units.getItemAt(i) as UIUnit).group = this;
}
}
public function onChanged(event:Event):void {
// display the 'save' button if it has not been shown yet.
}
}
class UIUnit extends EventDispatcher {
var group:UIGroup;
function onTextInput() {
group.onChanged(null);
}
}Version 2 does not use event dispatching. As a result, the overhead is removed. The flexibility has been reduced though. You can not add extra listeners to a UIUnit. However, this tradeoff is definitely acceptable in this situation since UIGroup and UIUnit are tightly coupled.
Use mono listener function if there is at most one event listener
In the above example, the components are tightly coupled. Is it possible to have components loose coupled without Flex's formal event dispatching mechanism? Yes, when there is only one possible event listener. For example, if we want to monitor the UIGroup's change status to enable/dispable the 'save' menu item on menu bar. We do not need UIGroup to have formal dispatch functions. Instead, we simply use a mono listener function:
class UIGroup {
var units:ArrayCollection;
public var changeListenerFunc:Function; // the mono listener function
public function UIGroup(units_:ArrayCollection) {
this.units = units_;
for(var i:int = 0; i < units.length; i++) {
(units.getItemAt(i) as UIUnit).group = this;
}
}
public function onChanged(event:Event):void {
// display the 'save' button if it has not been shown yet.
...
if(changeListenerFunc != null) { // notify the listener if any
changeListenerFunc(event);
}
}
}
class MyApplication {
var group:UIGroup;
function MyApplication() {
group.changeListenerFunc = onGroupChange; // register the listener.
}
function onGroupChange(event:Event) {
// update menu item 'save'.
}
}Which technique to use? There are tradeoffs. You need to consider the contexts and select wisely.