puremvc源代码解析

puremvc中把系统分成3部分,controller view model相互分离,通过notification进行各个部分的通信,这个通信是如何进行的呢。
我们知道,在Mediator、Proxy和Command中,可以调用sendNotification触发注册的Command和Mediator,那么sendNotification以后是怎么触发注册的Command和Mediator的?

     首先看一下notification的结构:
    notification实现INotification接口,存储三个属性name,body,type
    
sendNotification这个方法是INotifier这个接口中的,看下实现这个方法的类Notifier的中这个方法的定义
public function sendNotification( notificationName:String, body:Object=null, type:String=null ):void 
        {
            facade.sendNotification( notificationName, body, type );
        }
实际上是调用facde的sendNotification
看一下facade的这个方法
public function sendNotification( notificationName:String, body:Object=null, type:String=null ):void 
        {
            notifyObservers( new Notification( notificationName, body, type ) );
        }

这里创建了一个Notification对象,接着往下看

public function notifyObservers ( notification:INotification ):void {
            if ( view != null ) view.notifyObservers( notification );
        }
这里实际上是view调用notifyObservers,将刚才新建的notification传入,看一下这个方法
public function notifyObservers( notification:INotification ) : void
        {
            if( observerMap[ notification.getName() ] != null ) {
                var observers_ref:Array = observerMap[ notification.getName() ] as Array;
                   var observers:Array = new Array(); 
                   var observer:IObserver;
                for (var i:Number = 0; i < observers_ref.length; i++) { 
                    observer = observers_ref[ i ] as IObserver;
                    observers.push( observer );
                }        
                for (i = 0; i < observers.length; i++) {
                    observer = observers[ i ] as IObserver;
                    observer.notifyObserver( notification );
                }
            }
        }
这里在view中将注册的command和mediator放在observer 数组中,并用名字来进行了索引,最终调用的是
observer.notifyObserver( notification );


来看一下是怎么注册的,我们可以使用facade的registerXXX来注册Command和Mediator以及Proxy,其中Proxy并不接收Notification,那么来看一下,
先看Command
public function registerCommand( notificationName:String, commandClassRef:Class ):void 
        {
            controller.registerCommand( notificationName, commandClassRef );
        }
这里实际上调用的是  controller.registerCommand方法,继续追踪
public function registerCommand( notificationName : String, commandClassRef : Class ) : void
        {
if ( commandMap[ notificationName ] == null ) {
                view.registerObserver( notificationName, new Observer( executeCommand, this ) );
            }
            commandMap[ notificationName ] = commandClassRef;
        }

这里最终调用的是view.registerObserver方法,创建了Observer,并通过notificationName来索引这个Observer,那么observer是什么呢

来看一下Observer的构造函数
public function Observer( notifyMethod:Function, notifyContext:Object ) 
        {
            setNotifyMethod( notifyMethod );
            setNotifyContext( notifyContext );
        }
这里Observer保存的是上面controller类的executeCommand方法,和controller对象,
上面已经提到了,最终sendNotification是通过observer.notifyObserver( notification );这个方法执行的,那么这个方法具体干了什么呢

public function notifyObserver( notification:INotification ):void
        {
            this.getNotifyMethod().apply(this.getNotifyContext(),[notification]);
        }
这里调用刚才保存的方法,并传递notification对象,这里本质上是调用了
controller.executeCommand(notification),


public function executeCommand( note : INotification ) : void
        {
            var commandClassRef : Class = commandMap[ note.getName() ];
            if ( commandClassRef == null ) return;

            var commandInstance : ICommand = new commandClassRef();
            commandInstance.execute( note );
        }
在这里创建了command类的实例,并调用了execute方法,将notification对象传入。
所以最终sendNotification是通过名字找到具体的command类,并创建实例,并执行
以上是command的执行过程。


再来看看Mediator的注册

public function registerMediator( mediator:IMediator ):void 
        {
            if ( view != null ) view.registerMediator( mediator );
        }

view:
public function registerMediator( mediator:IMediator ) : void
        {
            if ( mediatorMap[ mediator.getMediatorName() ] != null ) return;
            mediatorMap[ mediator.getMediatorName() ] = mediator;
            var interests:Array = mediator.listNotificationInterests();
            if ( interests.length > 0 ) 
            {
                var observer:Observer = new Observer( mediator.handleNotification, mediator );
                for ( var i:Number=0;  i<interests.length; i++ ) {
                    registerObserver( interests,  observer );
                }            
            }
            mediator.onRegister();
            
        }
这里仍然是创建observer,保存mediator.handleNotification和mediator对象
那么sendNotification以后,通过mediator的listNotificationInterests数组中的名字,来索引到对应的Observer,
public function notifyObserver( notification:INotification ):void
        {
            this.getNotifyMethod().apply(this.getNotifyContext(),[notification]);
        }
这里本质调用了mediator.handleNotification,并传入参数notification对象。



综上所述,sendNotification实际上是通过名字来索引到对应的Observer,由Observer调用注册的Controller对象的executeCommand方法或者Mediator对象的handleNotification方法。
posted @ 2012-11-13 10:36  tinytiny  阅读(442)  评论(0编辑  收藏  举报