在我们的Flex项目开发中,Service通常是不可缺少的一部分(我们通常将数据交互相关的逻辑封装成Service层,比如您基于Flex做了一个CMS管理平台,那么和后台数据相关的操作(查询,增加,删除,修改),可以封装为Service,也可以进一步封装为Delegate+Service),至于具体通讯方式,可以是HTTP Service,Web Service,或Remote Object,您可以根据需求自己选择,这个并不影响我们对Sercice的定义。
然后就出现了一个问题,我们在开发的初始阶段,由于后台Server尚未准备好,我们需要在Flex端产生一些虚拟数据,来帮助我们的模块完成开发和测试,这就相当于我们临时使用了一个虚构的服务器,来代替真实的后端Server,这就是mock service的概念。
要完成这个功能,我们建议使用Delegate+Service的模式,将您的应用逻辑与Service解除耦合,这样方便我们临时注入一个mock service,而不影响您其它模块的代码。
至于mock service的具体编写方式,跟您对Delegate的封装方式有关。由于对Service的调用,都是异步调用,所以我们建议您用AsyncToken封装对Service的调用,同时将代理封装为一个接口实现。看一个抽象的例子:
IDelegate
public interface IDelegate { function login(user:User):AsyncToken; }
LoginDelegate.as
public class LoginDelegate implements IDelegate { public function login(user:User):AsyncToken { return service.login(user); } }
这里假设我们的Service是一个RemoteObject对象,通过IoC方式注入到了代理中。那么在项目初期,我们可以使用一个虚构的代理,来返回一些虚拟数据(在我们的逻辑代码中要使用接口的方式使用代理,而不是具体的代理实现类)。比如:
MockDelegate
public class MockDelegate implements IDelegate { public function login(user:User):AsyncToken { CursorManager.setBusyCursor(); logger.info("test delegate login调用:{0},{1}",user.userName,user.password); currentToken = new AsyncToken(); var returnData:ReturnData = new ReturnData(); if(user.userName == "jim" && user.password == "jim") { returnData.status = 1; returnData.info = "登录成功"; returnData.data = user; } else { returnData.status = 0; returnData.info = "用户名或密码错误"; } var evt:ResultEvent = new ResultEvent(ResultEvent.RESULT,false,true,returnData,currentToken); setTimeout(dataBack,1000,currentToken, evt); return currentToken; } private function dataBack(token:AsyncToken, result:ResultEvent):void { mx_internal:token.applyResult(result); CursorManager.removeBusyCursor(); } }
由于使用了代理,和接口的机制,那么基本上将具体Service的实现和我们其它部分的逻辑代码做了隔离,当后端Server准备好,我们只需要切换回真实的数据即可,而无需对其它部分的逻辑代码做改动。
转载:http://www.riadev.com/flex-thread-543-1-1.html