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。
具体的代码大家可以自己去看哈,这里就不引用了。呵呵,限于本人英语水平,许多注释只能意会,无法言传。希望大家批评指正。
下载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。
具体的代码大家可以自己去看哈,这里就不引用了。呵呵,限于本人英语水平,许多注释只能意会,无法言传。希望大家批评指正。
相关文章推荐
- PureMVC(AS3)剖析:实例
- PureMVC(AS3)备忘
- as3 解析xml 核心代码
- 对PureMVC(AS3版本) 的一些想法
- PureMVC(AS3)剖析:实例
- PureMVC(AS3)剖析:实例
- PureMVC(AS3)剖析:开篇
- PureMVC(AS3)剖析:吐槽
- PureMVC(AS3)剖析:设计模式(二)
- PureMVC(AS3)剖析:设计模式(一)
- PureMVC(AS3)剖析:设计模式(一)
- PureMVC(AS3)剖析:设计模式(二)
- PureMVC(AS3)剖析:开篇
- 【AS3 Coder】任务七:初涉PureMVC——天气预报功能实现
- PureMVC(AS3)剖析:设计模式
- PureMVC(AS3)剖析:开篇
- AS3版MP3播放器核心
- 【AS3 Coder】任务七:初涉PureMVC——天气预报功能实现
- PureMVC学习系列-从源码深度剖析PureMVC(核心组件工作流程及原理)
- PureMVC(AS3)剖析:开篇