简化复杂的Flash应用程序 谈熠

37
化化化化 化化化化化 FLASH 化化化化 谈谈 2010.5

description

 

Transcript of 简化复杂的Flash应用程序 谈熠

Page 1: 简化复杂的Flash应用程序 谈熠

化繁为简简化复杂的 FLASH 应用程序

谈熠2010.5

Page 2: 简化复杂的Flash应用程序 谈熠

简化开发,提高程序质量

简化开发

降低范错误的频率减少范错误的可能

提高代码质量精简代码实现

Page 3: 简化复杂的Flash应用程序 谈熠

程序设计方面的应用

Page 4: 简化复杂的Flash应用程序 谈熠

数据模型 和 E4X

E4X: 一个类似 Xpath ,针对 XML 数据检索方法 语法简单,速度快 适用的情况:

XMLSOCKET

XML 为基础的 HTTP 服务或者文件服务

思路: XML 、 XMLLIST 直接作为数据模型( Models )

Page 5: 简化复杂的Flash应用程序 谈熠

var thePeople:XML =<people> <person name="Mims Wright" suffix="III"> <age>27</age> <aka>Mims H Wright</aka> <aka>Teh AWesoeomes!</aka> <bio><!--[CDATA[This guy <b>rulz<b>!]]--></bio> </person> <person name="Roger Braunstein">      <age>26</age> <aka>Rog</aka> <aka>That guy</aka> <bio><!--[CDATA[Likes food.]]--></bio> </person> </people>;

Page 6: 简化复杂的Flash应用程序 谈熠

E4X 的用例 thePeople.person.age

//  得到:<age>27</age> <age>26</age>

thePeople.person.@name //  得到: XMLList: Mims Wright, Roger Braunstein

thePeople.person.(age >= 21) // 得到 :

<person name="Mims Wright" suffix="III"> <age>27</age> <aka>Mims H Wright</aka> <aka>Teh AWesoeomes!</aka> <bio><!--[CDATA[This guy <b>rulz<b>!]]--></bio> </person>

Page 7: 简化复杂的Flash应用程序 谈熠

采用 XML 直接作为 Model 的思路 一种常见的情况

建议的方式

继承 xMLList 容器 通过 getter 和 setter 来提供需要进行逻辑处理的数据访问

XML 数据源

数据模型实例

对数据进行处理的逻辑

XML 数据源封装为数据模型

对数据进行处理的逻辑

Page 8: 简化复杂的Flash应用程序 谈熠

元编程( Meta-programming )

一种根据在运行时的环境动态地获得、创建、修改程序所需要的类和对象的技巧。

Page 9: 简化复杂的Flash应用程序 谈熠

一个简单 AS 元编程应用 Object.method1()

Object.method2()

Object.method3()

Object[“method”+i]();

Page 10: 简化复杂的Flash应用程序 谈熠

AS3 中的元编程 ACTIONSCRIPT 是一门基于 Prototype 的语言 flash.utils.* 提供了一套反射工具方法 两个 AS3 的元编程技巧:

反射 ( Reflection ) 方法缺失 ( Method Missing )

两个编程概念 DRY

Convention Over Configuration

Page 11: 简化复杂的Flash应用程序 谈熠

反射 ( Reflection ) 工具: flash.utils.describeType 作用:返回一个对象的元数据的 XML 描述信息

Page 12: 简化复杂的Flash应用程序 谈熠

反射的应用 class ApplicationState

{

public static const LOGIN:uint=1;

public static const LOADING:uint=2;

public static const PLAYING:uint=3;

}

Page 13: 简化复杂的Flash应用程序 谈熠

反射的应用 class ApplicationState

{

public static const LOGIN:uint=1;

public static const LOADING:uint=2;

public static const PLAYING:uint=3;

}

Page 14: 简化复杂的Flash应用程序 谈熠

反射的应用 class ApplicationState

{

public static const LOGIN:uint=1;

public static const LOADING:uint=2;

public static const PLAYING:uint=3;

private static const stateNames:Object = {};

}

Page 15: 简化复杂的Flash应用程序 谈熠

反射的应用 class ApplicationState

{

...

public static function init():void

{

for each(var constantName:XML in

describeType(ApplicationState).constant.@name)

{

stateNames[ApplicationState[constantName.toString()]] =

constantName.toString();

}

}

}

...

Page 16: 简化复杂的Flash应用程序 谈熠

反射的应用 class ApplicationState

{

...

public static function getStateNameByValue(val:uint):String

{

return stateNames[val.toString()];

}

}

Page 17: 简化复杂的Flash应用程序 谈熠

反射的应用

var currentState:uint = ApplicationState.LOADING;

trace(currentState); // 1

trace(

ApplicationState.getStateNameByValue(currentState)

); // "LOGIN"

Page 18: 简化复杂的Flash应用程序 谈熠

概念 1 :干 干 —— 避免重复 DRY – Don’t Repeat Yourself

一种常见的重复操作: trace(“name:”+this.name+”, data:”+this.data);……

Page 19: 简化复杂的Flash应用程序 谈熠

反射在调试时的应用 class Inspector

/**

* 列出一个对象中的所有公开变量名,并把这些变量名放在一个 Vector.<String> * 容器中 * @param obj object of any kind

* @return 列出一个对象中的所有公开变量名,并把这些变量名放在一个 * Vector.<String> 容器中 */ public static function listInstanceVariables(obj:*):Vector.<String>

{

return xmlListToStringList(describeType(obj).variable.@name);

}

public static function dumpInstanceVariables(obj:*):Vector.<String>

{

return dumpProperty(listInstanceVariables(obj),obj);

}

Page 20: 简化复杂的Flash应用程序 谈熠

反射在调试时的应用 trace(Inspector. dumpInstanceVariables(this));

Page 21: 简化复杂的Flash应用程序 谈熠

方法缺失 ( Method Missing ) 工具: flash.utils.Proxy

作用:重载 AS 对象默认的操作行为 原理:

Object extends flash.utils.Proxy

Object.methodName(arg0,arg1)

Object.callProperty(“methodName”,args)

Page 22: 简化复杂的Flash应用程序 谈熠

方法缺失 public dynamic class ClassA extends Proxy

{

flash_proxy override function callProperty(name:*, ...rest):*

{

trace(“ 请求调用方法 :”+name)

}

}

var instanceA:ClassA = new ClassA();

instanceA.doSomeThing(); // 请求调用方法 :doSomeThing

Page 23: 简化复杂的Flash应用程序 谈熠

概念 2 :习惯优于配置 习惯优于配置 Convention Over Configuration

惯例优于配置的宗旨是减轻配置文件的负担。我们要保留应用程序和程序框架的基本可扩展性,同时去掉无休止的配置信息。

AS 的”方法缺失”技术非常适用于大配置量的情况。

Page 24: 简化复杂的Flash应用程序 谈熠

元编程的使用建议 元编程的关键是你编写程序在它们运行的时候调整

和修改它们自身。元编程被使用的越多,你的运行程序就越不象你所编写的源代码。这当然是这个模式的意义所在,不过同时也是危险所在。

调试普通代码已经不是件容易的事情,而要调试元编程所产生的短暂存在的对象则要更困难许多。

因此,一组完整的单元测试是使程序正常工作的关键。如果你的程序使用了大量的元编程技术,那么单元测试是绝对必不可少的。

Page 25: 简化复杂的Flash应用程序 谈熠

对开发流程的思考

Page 26: 简化复杂的Flash应用程序 谈熠

为了便于表达,我设置两个变量

代表:客户端组client-side guys

代表:服务器组server-side guys

Page 27: 简化复杂的Flash应用程序 谈熠

常见的开发工作流程

一种紧密耦合的状态tightly coupled

低效,易出错,难管理

Page 28: 简化复杂的Flash应用程序 谈熠

解耦客户端的开发

吃过了吗?

还没,您呢? <hello> 吃了吗 </hello>

{hello:“吃了吗”}

010011101001101

…/hello/ 吃了吗

Page 29: 简化复杂的Flash应用程序 谈熠

采用代理模式( Proxy Pattern )

Server

send()

ServerProxy

@connectionObject

send()

RealConnection

send()

function send(){ connectionObject.send()}

RealConnection 可能是 xml, json, bin socket, restful http …

Page 30: 简化复杂的Flash应用程序 谈熠

用 flash.utils.Proxy 优化代理实现

server.walkTo(x,y) // 发出 socket 数据包 “WALKTO X Y“ server.attach(targetId) // 发出 socket 数据包 “ ATTACK targetId“

server.method()callProperty(“method

”,[...])

编译并发送通信指令

Page 31: 简化复杂的Flash应用程序 谈熠

优化后开发团队工作流程

优点:- 降低团队之间的依赖- 工作效率提高,调试难度降低

系统整合

Page 32: 简化复杂的Flash应用程序 谈熠

更有效的技术交流

Page 33: 简化复杂的Flash应用程序 谈熠

QQ 群。。。唉。。 QQ 群

Page 34: 简化复杂的Flash应用程序 谈熠
Page 35: 简化复杂的Flash应用程序 谈熠
Page 36: 简化复杂的Flash应用程序 谈熠
Page 37: 简化复杂的Flash应用程序 谈熠

谢谢,谈熠