您的位置:首页 > 其它

AS3 PureMVC之核心层

2012-03-23 15:25 246 查看
原文:http://uh.9ria.com/space-44647-do-blog-id-4823.html

下载PureMVC的源代码并导入到FB4后,我们可以看到org.puremvc.as3这个包,其中有个core包,这里面的就是PureMVC的核心包。

我们可以看到核心包里面有三个类:Model, View, Controller。这是经典MVC元设计模式中的三个类。我们查看一下这三个类的原代码,可以发现这三个类都是单例模式类。

这些稍稍提下这三个类的单例实现方法,如Model类

public function Model( )

{

if (instance != null) throw Error(SINGLETON_MSG);

instance = this;

proxyMap = new Array();

initializeModel();

}

/**

* <code>Model</code> Singleton Factory method.

*

* @return the Singleton instance

*/

public static function getInstance() : IModel

{

if (instance == null) instance = new Model( );

return instance;

}

我们可以看到在构造函数中if (instance != null) throw Error(SINGLETON_MSG);如果实例为空,则抛出一个异常,这样我们就无法通过构造函数来实例化这个类,而必须通过getInstance()方法来创建并返回一个实例。呵呵,这个实现比较有意思。之前了解的单例的实现方法是能过在as文本中的包外声明一个类,将这个类对象做为需要单例的类的构造函数的参数,这样阻止了外部通过构造函数来实例化这个类了。

下面我们一个类一个类来分析下源代码吧

Model

Model类用于保存对Proxy对象的引用,并通过Proxy来操作数据模型,与远程服务通信存取数据。Model类实现了IModel接口。IModel接口声明了如下四个方法,这些方法主要是通过名称来操作Proxy实例对象(除registerProxy):

function registerProxy( proxy:IProxy ) : void; //用于注册Proxy实例

function retrieveProxy( proxyName:String ) : IProxy; //用于获取名为proxyName的Proxy实例

function removeProxy( proxyName:String ) : IProxy; //移除名为proxyName的Proxy实例

function hasProxy( proxyName:String ) : Boolean; //判断是否有名为proxyName的Proxy实例

Model类中有一个proxyMap数组,这个数组通过关联数组的方式来存储Proxy实例,在实现IModel接口的方法中,通过处理这个数组来管理Proxy实例对象,如下

/**

* Register an <code>IProxy</code> with the <code>Model</code>.

*

* @param proxy an <code>IProxy</code> to be held by the <code>Model</code>.

*/

public function registerProxy( proxy:IProxy ) : void

{

proxyMap[ proxy.getProxyName() ] = proxy;

proxy.onRegister();

}

View

View保存了对Mediator对象的引用,并通过Mediator对象来操作具体的视图组件(这些操作包括添加事件监听器、发送或接收Notification、直接改变视图组件的状态)。View类实现了IView接口,IView接口声明了如下方法:

function registerMediator( mediator:IMediator ) : void; //注册Mediator对象

function retrieveMediator( mediatorName:String ) : IMediator;//获取Mediator对象

function removeMediator( mediatorName:String ) : IMediator;//移除Mediator对象

function hasMediator( mediatorName:String ) : Boolean; //决断是否有Mediator对象

function registerObserver( notificationName:String, observer:IObserver ) : void;//注册一个Observer对象

function removeObserver( notificationName:String, notifyContext:Object ):void;//移除一个Observer对象

function notifyObservers( note:INotification ) : void; //通知Observer对象

从这些方法中我们可以看出View的主要任务应该是分成两部分:管理Mediator和处理消息。因此,View中有保存了两个数组:mediatorMap(保存Madiator名与Mediator对象的映射)和observerMap(保存Observer名与Observer对象列表的映射:注意,这是列表),当然因为Observer列表是与Mediator相关的,所以在处理Mediator对象时,也相应滴处理了相关的Observer列表,如下:

/**

* Register an <code>IMediator</code> instance with the <code>View</code>.

*

* <P>

* Registers the <code>IMediator</code> so that it can be retrieved by name,

* and further interrogates the <code>IMediator</code> for its

* <code>INotification</code> interests.</P>

* <P>

* If the <code>IMediator</code> returns any <code>INotification</code>

* names to be notified about, an <code>Observer</code> is created encapsulating

* the <code>IMediator</code> instance's <code>handleNotification</code> method

* and registering it as an <code>Observer</code> for all <code>INotifications</code> the

* <code>IMediator</code> is interested in.</p>

*

* @param mediatorName the name to associate with this <code>IMediator</code> instance

* @param mediator a reference to the <code>IMediator</code> instance

*/

public function registerMediator( mediator:IMediator ) : void

{

// Register the Mediator for retrieval by name

mediatorMap[ mediator.getMediatorName() ] = mediator;

// Get Notification interests, if any.

var interests:Array = mediator.listNotificationInterests();

// Register Mediator as an observer for each of its notification interests

if ( interests.length > 0 )

{

// Create Observer referencing this mediator's handlNotification method

var observer:Observer = new Observer( mediator.handleNotification, mediator );

// Register Mediator as Observer for its list of Notification interests

for ( var i:Number=0; i<interests.length; i++ ) {

registerObserver( interests[i], observer );

}

}

// alert the mediator that it has been registered

mediator.onRegister();

}

Controller

Controller保存所有的Command的映射。

Controller类实现了IController接口。该接口声明了如下方法:

function registerCommand( notificationName : String, commandClassRef : Class ) : void; //注册Command

function executeCommand( notification : INotification ) : void; //执行Command

function removeCommand( notificationName : String ):void; //移除Command

function hasCommand( notificationName:String ) : Boolean; //是否有Command

Controller保存一个数组commandMap,该数组用于保存Notification名与Command类引用的映射。这里需要注意的是Command类是无状态的,只有在需要时才被创建。Command可以获取Proxy对象并与之交互,发送Notification,执行其他的Command。所以执行Command的代码如下:

/**

* If an <code>ICommand</code> has previously been registered

* to handle a the given <code>INotification</code>, then it is executed.

*

* @param note an <code>INotification</code>

*/

public function executeCommand( note : INotification ) : void

{

var commandClassRef : Class = commandMap[ note.getName() ];

if ( commandClassRef == null ) return;

var commandInstance : ICommand = new commandClassRef();

commandInstance.execute( note );

}

上面就是核心层的相关信息。当然不够全面,大家可以去分析一下,并查看代码的详细注释。

Façade

了解了核心类,当然还需要知道如何去用咯,不过对于我们而言,并不需要在实际代码中用到这几个类,PureMVC都替我们做好了。而整个处理过程就是通过Façade了。这也是个单例类,它负责初始化核心层,并能访问它们的public方法。这样,在实际的应用中,只需继承Façade类创建一个具体的Façade类就可以实现整个MVC模式,并不需要在代码中导入Model,
View, Controller。

具体的代码大家可以自己去看哈,这里就不引用了。呵呵,限于本人英语水平,许多注释只能意会,无法言传。希望大家批评指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: