• 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方法。
  • 相关阅读:
    oracle 误删除表的几种恢复方法
    解决js在alert或者断点调试时才能赋值
    常用的Debug方式
    字节对齐
    CWnd::SetWindowPos的注意事项
    网络模块代码调试要点
    stub和mock
    全局变量的缺陷
    SVN切换地址
    C/C++如何得到int型最大值
  • 原文地址:https://www.cnblogs.com/tinytiny/p/2767573.html
Copyright © 2020-2023  润新知