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方法。 |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法