uedbet手机官网下载-uedbet手机app下载
PureMVC不仅仅是AS的经典MVC模式的框架,同时也有其他语言的实现,比如JS,php,C#。我接触PureMVC也只是这半年里的事,伴随着一个项目应用了这个边学边用的AS3框架。PureMVC很容易使用,那时我参考的是Cliff Hall的Best Practices,例子讲述了一个使用PureMVC的登陆过程。非常详细,而且很多注意点提示地都非常深刻。
PureMVC不是基于flash本身的事件机制,而是采用了一种发送通知的观察者机制。这里主要分析这种通知的机制。
首先是INotifier.as
public interface INotifier
{
function sendNotification( notificationName:String, body:Object=null, type:String=null ):void;
}
这个类只有一个sendNotification()
方法。我们知道,PureMVC里全部的模块(command, mediator, proxy, facade)都可以发送通知,所以它们都实现了INotifier接口。所不同的是proxy不接受任何的通知,它只是送出通知。所以对于proxy来说,它不注册监视通知并作出动作的observer。
Observer类直接实现了IObserver接口,后者只有简单的4个方法定义。Observer则在这4个方法的基础上增加了对应类成员的get方法。对于Observer类来说,最重要的是notifyObserver()
方法。
public function notifyObserver( notification:INotification ):void
{
this.getNotifyMethod().apply(this.getNotifyContext(),[notification]);
}
这个方法将调用对应于某个对象的方法来接受并处理通知。
对于mediator来说,就是调用其自身的handleNotification()
方法。这点可以从View.as中看到。
// Create Observer referencing this mediator's handlNotification method
var observer:Observer = new Observer( mediator.handleNotification, mediator );
而对于command来说,就是调用Controller的executeCommand()
方法,这个方法实例化对应的command然后调用其execute()
去具体执行一个通知行为。
在controller.as中,registerCommand()
里调用的是view的registerObserver()
。
public function registerCommand( notificationName : String, commandClassRef : Class ) : void
{
if ( commandMap[ notificationName ] == null ) {
view.registerObserver( notificationName, new Observer( executeCommand, this ) );
}
commandMap[ notificationName ] = commandClassRef;
}
当observer通知执行某个command时,首先调用的就是controller的executeCommand()
,随后这个方法里,依据commandMap的映射关系,找出对应于该通知的command,然后实例化,调用execute()
执行。
public function executeCommand( note : INotification ) : void
{
var commandClassRef : Class = commandMap[ note.getName() ];
if ( commandClassRef == null ) return;
var commandInstance : ICommand = new commandClassRef();
commandInstance.execute( note );
}
那么notifyObserver()
是由谁调用的?作为整个observer的核心调度方法,View类的notifyObservers()
将通知派发到全部相关的observer那里。
public function notifyObservers( notification:INotification ) : void
{
if( observerMap[ notification.getName() ] != null ) {
// Get a reference to the observers list for this notification name
var observers_ref:Array = observerMap[ notification.getName() ] as Array;
// Copy observers from reference array to working array,
// since the reference array may change during the notification loop
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 );
}
// Notify Observers from the working array
for (i = 0; i < observers.length; i++) {
observer = observers[ i ] as IObserver;
observer.notifyObserver( notification );
}
}
}
首先,获取对应某个通知的observer的列表引用。这个observerMap是在注册observer时被赋值的一个通知对应observer数组的数组。当用通知名索引这个observerMap时得到的就是一个相关observer的数组。
然后拷贝这个相关observer数组,因为持有这个数组的引用是不够的,这个数组可能会在整个通知过程中被更改。
最后,对每个observer调用自身的notifyObserver()
方法。这样原先注册过的这个通知的方法就会开始执行。到这里,整个观察者机制就已经差不多了。
回过头来看Facade,真是应有尽有!不仅持有全部核心类的引用,所有添加、移除、获取方法一应俱全~所以Facade无所不能,在整个PureMVC里起到一个核心作用。它调用相应的model、controller、view的方法,而这几个核心类,各自管理着自己的那部分模块。
PureMVC AS3很简练,很轻量,10个接口,11个类,代码简洁而优雅,虽然在应用上可能是有局限性的(有人说它高不成低不就),但它绝对是一个优秀的框架