在一年多的项目开发里,我经常会遇到这种情况:每当处理一个业务逻辑,都会创建一个独立的事件类来发送成功或失败执行的事件。后来,接触了一些有关设计模式知识,我就独立写了一个公共类来抽象出业务逻辑,那就是action,可以理解为动作、命令。有了这个类后,做项目时就顺畅多了,但凡是涉及到业务逻辑的,我就用action来封装它。
在创建action前,遵循面向接口编程的原则,我首先创建了一个IAction接口类:
代码:
然后创建Action类,让它实现IAction接口:
代码:
还有创建了一个继承于Action的ActionsProxy类,用于顺序执行多个Action动作:
代码:
ActionEvent动作事件,用来统一发送动作执行成功或失败事件:
代码:
ActionUtil是动作工具类,负责处理ActionEvent事件:
代码:
在创建action前,遵循面向接口编程的原则,我首先创建了一个IAction接口类:
代码:
/**
*动作(命令)接口
*/
package sunnyluo.action
{
import flash.events.IEventDispatcher;
public interface IAction extends IEventDispatcher
{
function execute(event:ActionEvent = null):void; //执行动作
function getActionName():String; //获取动作名称
function actionCompleteHandler(data_:* = null):void; //动作完成
function actionErrorHandler(data_:* = null):void; //动作失败
function destroy():void; //销毁动作
}
}
然后创建Action类,让它实现IAction接口:
代码:
/**
*定义一个动作
*/
package sunnyluo.action
{
import flash.events.EventDispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
[Event(name="actionComplete", type="sunnyluo.action.ActionEvent")]
[Event(name="actionError", type="sunnyluo.action.ActionEvent")]
public class Action extends EventDispatcher implements IAction
{
protected var _actionName:String = ""; //动作名称
protected var _liveTimer:Timer; //动作计时器
protected var _timeToLive:Number = 0.0; //动作生命时间
public function Action(name_:String = "")
{
_actionName = name_;
}
/* 开始执行动作 */
public function execute(event:ActionEvent = null):void
{
}
/* 获取动作名称 */
public function getActionName():String
{
return this._actionName;
}
/* 发送执行动作完成事件 */
public function actionCompleteHandler(data_:* = null):void
{
removeLiveTimer();
this.dispatchEvent(new ActionEvent(ActionEvent.ACTION_COMPLETE, data_));
}
/* 发送执行动作错误事件 */
public function actionErrorHandler(data_:* = null):void
{
removeLiveTimer();
this.dispatchEvent(new ActionEvent(ActionEvent.ACTION_ERROR, data_));
if(_actionName)
{
trace("action error:" + this._actionName);
}
}
/* 开始动作计时 */
public function startLiveTimer():void
{
if(_timeToLive <= 0.0)
{
return;
}
_liveTimer = new Timer(_timeToLive, 1);
_liveTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onLiveTimerComplete);
_liveTimer.start();
}
/* 动作计时完成,发送动作执行错误事件,并带上超时参数 */
protected function onLiveTimerComplete(event:TimerEvent):void
{
this.actionErrorHandler(ActionEvent.ACTION_TIME_OUT);
}
/* 移除动作计时 */
protected function removeLiveTimer():void
{
if(_liveTimer)
{
_liveTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, onLiveTimerComplete);
_liveTimer.stop();
_liveTimer = null;
}
}
/* 设置动作生命时间 */
public function set timeToLive(value:Number):void
{
_timeToLive = value;
}
/* 销毁动作 */
public function destroy():void
{
removeLiveTimer();
}
}
}
还有创建了一个继承于Action的ActionsProxy类,用于顺序执行多个Action动作:
代码:
/**
* 执行一系列的动作
*/
package sunnyluo.action
{
import flash.events.Event;
[Event(name="actionsOneResult", type="sunnyluo.action.ActionEvent")]
public class ActionsProxy extends Action
{
public var isAlwaysExecute:Boolean = false; //是否一直执行动作(不管某个动作发生错误)
protected var _actions:Array = []; //动作数组
protected var _curAction:IAction; //当前执行的动作
protected var _actionIndex:int = -1; //当前执行的动作序号
protected var _data:* = new Object();
protected var _stoped:Boolean = false;//是否停止动作执行
public function ActionsProxy(name_:String = "")
{
super(name_);
}
//开始执行一系列动作
override public function execute(event:ActionEvent = null):void
{
if(! _actions || _actions.length == 0)
{
this.actionCompleteHandler();
return;
}
executeOneAction();
}
/* 添加一个动作 */
public function addOneAction(action_:IAction):void
{
if(action_)
{
_actions.push(action_);
}
}
/* 添加一组动作 */
public function addActions(actions_:Array):void
{
_actions = _actions.concat(actions_);
}
/**
* 执行一个action 操作
*
*/
protected function executeOneAction():void
{
_actionIndex ++;
if(_actionIndex >= _actions.length)
{
completeAllHandler();
return;
}
var __action:IAction = _actions[_actionIndex];
if(! __action)
{
executeOneAction();
return;
}
_curAction = __action;
ActionUtil.addActionHandler(_curAction, onActionResult, onActionResult);
__action.execute();
}
/**
* 执行一个动作后的处理,
* 判断动作是否执行正确,是否需要执行新的操作
* @param event
*
*/
protected function onActionResult(event:ActionEvent):void
{
if(event &&(event.type == ActionEvent.ACTION_ERROR))
{
var __errorStr:String = (event.target as IAction).getActionName();
trace("action error:", __errorStr);
//动作执行错误时,判断是否继续执行其它动作
if(! isAlwaysExecute)
{
this.actionErrorHandler();
return;
}
}
completeOneHandler();
}
/* 移除当前动作 */
protected function removeCurAction():void
{
if(_curAction)
{
ActionUtil.removeActionHandler(_curAction);
_curAction.destroy();
_curAction = null;
}
}
/* 完成一个动作后执行 */
protected function completeOneHandler():void
{
if(! _stoped)
{
//发送一个动作执行完成的事件
this.dispatchEvent(new ActionEvent(ActionEvent.ACTIONS_ONE_RESULT, event));
removeCurAction();
executeOneAction();
}
}
/* 完成所有动作后执行 */
protected function completeAllHandler():void
{
super.actionCompleteHandler(_data);
}
//销毁动作
override public function destroy():void
{
_stoped = true;
removeCurAction();
_actions = null;
}
/**
* 获取动作数组
* @return
*
*/
public function getActions():Array{
return _actions;
}
/**
* 获取当前正在执行的动作的序号
* @return
*
*/
public function getCurActionIndex():int
{
return _actionIndex;
}
/**
* 获取动作数组长度(动作个数)
* @return
*
*/
public function getActionsLength():int
{
return _actions ? _actions.length : 0;
}
}
}
ActionEvent动作事件,用来统一发送动作执行成功或失败事件:
代码:
/**
* 动作事件
*/
package sunnyluo.action
{
import flash.events.Event;
public class ActionEvent extends Event
{
public static const ACTION_COMPLETE:String = "actionComplete"; //执行动作成功事件
public static const ACTION_ERROR:String = "actionError"; //执行动作错误事件
public static const ACTION_TIME_OUT:String = "actionTimeOut"; //执行动作超时
public static const ACTIONS_ONE_RESULT:String = "actionsOneResult"; //执行多个动作时,有一个执行结果(成功或失败)事件
public var data : *; //动作数据
public function ActionEvent(type:String, data_:* = null, bubbles:Boolean=false, cancelable:Boolean=false)
{
data = data_;
super(type, bubbles, cancelable);
}
}
}
ActionUtil是动作工具类,负责处理ActionEvent事件:
代码:
/**
* 动作的工具类
*/
package sunnyluo.action
{
import flash.utils.Dictionary;
public class ActionUtil
{
private static var _actionLis:Dictionary = new Dictionary(); //记录动作的侦听
public function ActionUtil()
{
}
/**
* 添加动作侦听
* @param action_ 要侦听的动作
* @param completeFunc_ 动作完成时执行的函数
* @param errorFunc_ 动作发生错误时执行的函数
* @return
*
*/
public static function addActionHandler(action_:IAction, completeFunc_:Function = null, errorFunc_:Function = null):IAction
{
action_.addEventListener(ActionEvent.ACTION_COMPLETE, onActionComplete, false, 0, true);
action_.addEventListener(ActionEvent.ACTION_ERROR, onActionError, false, 0, true);
//action_.execute();
_actionLis[action_] = [onActionComplete, onActionError];
return action_;
//动作执行成功处理
function onActionComplete(event: ActionEvent):void
{
removeActionHandler(action_);
if(completeFunc_ != null)
{
completeFunc_(event);
}
}
动作执行错误处理
function onActionError(event: ActionEvent):void
{
removeActionHandler(action_);
if(errorFunc_ != null)
{
errorFunc_(event);
}
}
}
/* 移除动作的侦听 */
public static function removeActionHandler(action_:IAction):void
{
if(! action_ || ! _actionLis[action_])
{
return;
}
if(action_.hasEventListener(ActionEvent.ACTION_COMPLETE))
{
action_.removeEventListener(ActionEvent.ACTION_COMPLETE, _actionLis[action_][0]);
}
if(action_.hasEventListener(ActionEvent.ACTION_ERROR))
{
action_.removeEventListener(ActionEvent.ACTION_ERROR, _actionLis[action_][1]);
}
delete _actionLis[action_];
}
}
}