开发框架使用手册
目录(目录结构==类文件的文件夹结构)
1 patterns包 1.1 开发框架 1.2 框架结构 1.3 使用方法
1.4 “高内聚低耦合”的实现——程序架构要点 2 Facade类 3 mvc包 3.1 Model类 3.2 View类 3.3 Controller类 4 media包 4.1 Proxy类 4.2 Mediator类 4.3 Command类 4.4 Commands类 5 observer包 5.1 Observer类 5.2 Notifier类 5.3 Notice类
正文
1 patterns包
是开发框架的顶级包,应该放在程序的类目录的根目录下。 1.1 开发框架
开发框架就是一个空架子,我们可以自己加工、创造零部件,装配上去,使这个系统按照我们的设计意图运行起来。
这个开发框架基于PureMVC框架构建,目标是开发出更健壮、易维护、易扩展、可重用的应用程序。当然,采用这个开发框架并不等于实现了这个目标,要实现这个目标,还需要我们在开发过程中不断调整、不断优化程序架构。实现这个目标的关键是,降低模块间的耦合度。 1.2 框架结构
这个开发框架分为低耦合的三个层Model、View和Controller。这三部分由三个单例模式类管理,三者合称为核心层。还有一个单例模式类——Fa?ade,是整个系统的管理者。
简单地说,就是三个核心层、一个管理者,其余的就是零部件,可以按需增减。 其架构如下图所示:
其中:
▲ Model负责保存Proxy名称与实例的映射,根据Proxy名称获取其实例。Proxy负责保存数据对象,存取数据。
▲ View负责保存Mediator名称与实例的映射、Notice名称与观察者的映射,根据Mediator名称获取其实例,根据Notice通知其观察者。Mediator负责保存视图组件,操作具体的视图组件,处理通知。观察者负责保存通知的处理者及其处理方法,收到通知则告知其处理者处理这个通知。
▲ Controller负责保存Notice名称与Command类的映射,执行通知对应的Command。Command负责执行业务逻辑处理通知。
▲ Fa?ade是框架的管理者和通信中心,是框架与外界通信的唯一接口,负责初始化Model、View、Controller单例,发送通知。 1.3 使用方法
开发框架只是搭建了一个空架子,我们所要做的就是编写具体的Command、Mediator、Proxy等这些零部件,给它们添加自定义属性和方法,保存到Model、View、Controller中。在没有保存Proxy、Mediator和Observer、Command时,Model、View、Controller就是一个空架子。
通常,我们需要自定义视图组件:影片剪辑或声音放在Flash库中,它们对应的类文件放在包中,Flash的舞台就是一个自定义视图组件,文档类就是舞台对应的类文件。有时,还需要自定义事件、声音对象、数据对象等等。 1.4 “高内聚低耦合”的实现——程序架构要点 1.4.1 什么是高内聚低耦合?
简单地说,就是模块之间不直接互相操作,而是通过中介:通知、事件来实现互操作。 举例一:程序中有两个对象A、B,当A发生变化时,需要B随之变化。
如果A发生变化时,只发出通知或触发事件,B负责响应,那么A、B之间就是低耦合关系。A、B不必知道对方的实现细节。
如果A发生变化时,直接调用B的接口,使B发生相应变化,并获取操作结果,那么A、B之间就是强耦合关系。A、B需要知道对方的一些实现细节(属性或方法)。
举例二:球场上打比赛,As是裁判、Bs是球员,As与Bs需要合作。
如果比赛需要暂停,As只是吹哨,Bs听到号令就停下来,那么As、Bs之间就是低耦合关系。As、Bs不必抓住对方手脚。
如果比赛需要暂停,As直接走过去把Bs控制住,使Bs无法继续行动,那么As、Bs之间就是强耦合关系。
实现手段——程序架构要点 1、采用事件模型 2、采用通知机制
3、事件模型和通知机制的结合
2 Facade类
包:patterns
类:public class Fa?ade 实现:Fa?ade?IFacade Fa?ade是框架的管理者和通信中心,是框架与外界通信的唯一接口,放在顶级包中,负责初始化Model、View、Controller单例,发送通知。 2.1 属性
//===========只允许自己和子类访问 ================ protected var model:Model; // Model单例 protected var view:View; // View单例
protected var controller:Controller; // Controller单例 protected static var instance:Facade; // Facade单例
protected const SINGLETON_MSG:String = \ //消息常量 (通常,在自定义Fa?ade类中定义通知名称常量。因为系统全局都要用。) 2.2 方法
public function Facade() //构造函数,由于Facade是单例,所以应调用单例工厂方法Facade.getInstance(),而不能直接调用该构造函数,否则会抛出异常
protected function initFacade():void //初始化Facade单例,子类可追加不要替换 public static function getInstance():Fa?ade // Facade单例工厂方法
//===================== 创建三个核心层 ========================== protected function initModel():void //在自定义Fa?ade子类中,若想创建自定义Model并且自定义Proxy初始化时不需要引用Facade,可以重写这个方法,否则就先调用这个方法,再注册Proxy。注意:这个方法很少被重写,实践中,你更喜欢用command创建并注册Proxy,因为存有可变数据的Proxy很可能需要发送Notice,因此在创建时需要引用Facade。
protected function initView():void //在自定义Fa?ade子类中,若想创建自定义View,或想注册自定义Observers,可以重写这个方法,否则就先调用这个方法,再注册Mediator。注意:这个方法很少被重写,实践中你更可能使用command创建并注册Mediator,因为Mediator实例需要发送Notice,因此在创建时需要引用Fa?ade。
protected function initController():void //在自定义Facade子类中,若想创建自定义Controller,可以重写这个方法,否则就先调用这个方法,再注册command
//=================== 与Model层的交互 ========================= public function addProxy ( proxy:IProxy ):void //添加proxy实例到Model中
public function retrieveProxy ( proxyName:String ):IProxy //从Model中获取proxy实例 public function removeProxy ( proxyName:String ):IProxy //从Model中移除proxy实例 public function hasProxy( proxyName:String ):Boolean //判断Model中是否有proxy实例 //=================== 与View层的交互 =========================
public function addMediator( mediator:IMediator ):void //添加mediator实例到View中 public function retrieveMediator( mediatorName:String ):IMediator //从View中获取
实例
public function removeMediator( mediatorName:String ):IMediator //从View中移除mediator实例
public function hasMediator( mediatorName:String ):Boolean //判断View中是否有mediator实例
//=================== 与Controller层的交互 ========================= public function addCommand( noticeName:String, cmd:Class ):void //添加Command类到Controller中
public function removeCommand( noticeName:String ):void //从Controller中移除noticeName 对应的Command类
public function hasCommand( noticeName:String ) : Boolean //判断Controller中是否有noticeName 对应的Command类
//=============== 与Observer的交互,实现通信机制 =================
public function sendNotice( noticeName:String, body:Object=null, type:String=null ):void //创建并发送一个通知,这样,我们在实现代码中,就不用再创建通知实例了。
public function notifyObservers( notice:INotice ):void //公开这个方法,主要是为了向下兼容,允许你使用fa?ade发送自定义通知。通常,你可以只调用sendNotice方法,根本不需要自己创建通知。
3 mvc包
只有三个核心类,是三个单例,分别实现MVC三个核心层,是框架的主体(media是配件),不可增减。 3.1 Model类
包:patterns.mvc
类:public class Model 实现:Model ?IModel
负责保存Proxy名称与实例的映射,根据Proxy名称获取其实例。 3.1.1 属性
//================= 只允许自己和子类访问 =================== protected var proxyMap:Object; //保存Proxy名称与实例的映射 protected static var instance:Model; //Model单例
protected const SINGLETON_MSG:String = \ //消息常量 3.1.2 方法
public function Model() //Model是单例,不能直接调用该构造函数,而应该调用单例工厂方法Model.getInstance(),否则抛出异常
protected function initModel():void //自动被构造函数调用,若自定义子类,则在这里添加自定义内容,而不必override构造函数
public static function getInstance():Model //Model的单例工厂静态方法 //============== 操作Proxy实例的接口 ==================
public function addProxy( proxy:IProxy ):void //把Proxy实例赋值给proxyMap的属性,Proxy的名称作为proxyMap属性名
public function retrieveProxy( proxyName:String ):IProxy //以proxyName为关键字,获取proxyMap的属性对应的Proxy实例
public function removeProxy( proxyName:String ):IProxy //把proxyMap的属性名为
的属性干掉
public function hasProxy( proxyName:String ):Boolean //判断proxyMap的属性名为proxyName的属性是否存在 3.2 View类
包:patterns.mvc 类:public class View 实现:View?IView
View负责保存Mediator名称与实例的映射、Notice名称与观察者的映射,根据Mediator名称获取其实例,根据Notice通知其观察者。 3.2.1 属性
//================= 只允许自己和子类访问 ===================
protected var mediatorMap:Object; //存储Mediator名称到Mediator实例的映射 protected var observerMap:Object; //存储Notice名称到观察者列表的映射 protected static var instance:View; //View单例
protected const SINGLETON_MSG:String = \ //消息常量 3.2.2 方法
public function View() //View是单例,不能直接调用该构造函数,而应调用单例工厂方法View.getInstance(),否则会抛出异常
protected function initView():void //自动被构造函数调用,若自定义子类,就在这里设定自定义内容,而不必override构造函数
public static function getInstance():View //View的单例工厂方法
//=============== 对观察者的操作 ======================
public function addObserver( noticeName:String, observer:IObserver ):void //把observer存入观察者列表中,收到通知,就遍历对应的观察者列表,通知各个observer
public function notifyObservers( notice:INotice ):void //通知notice的观察者列表中的所有观察者
public function removeObserver( noticeName:String, processor:Object ):void //根据processor从noticeName的观察者列表中移除观察者
//=========== 对Mediator的操作 =========================
public function addMediator( mediator:IMediator ):void //首先把Mediator实例赋值给mediatorMap的属性,mediatorName作为属性名。然后,通过名称获取Mediator实例,并进一步查询它所关心的Notice。若返回Notice列表,则创建观察者(封装Mediator实例及其handleNotice方法),把观察者注册给列表中的每个Notice。最后,触发Mediator实例的被注册事件。
public function retrieveMediator( mediatorName:String ):IMediator //根据Mediator名称获取Mediator实例
public function removeMediator( mediatorName:String ):IMediator //首先根据Mediator名称获取Mediator实例,若该Mediator实例存在,则查询该mediator实例所关心的Notice,把mediator实例相关的观察者从notice的观察者列表中删除。然后,把该mediator实例从mediatorMap中删除。最后,触发mediator实例的被删除事件。
public function hasMediator( mediatorName:String ):Boolean //判断View的mediatorMap中是否有这个mediator实例 3.3 Controller类 包:patterns.mvc