每位 Java 开发人员都应该了解的关于 Flex 的 10 件事






4.33/5 (2投票s)
每位 Java 开发人员都应该了解的关于 Flex 的 10 件事
Java 开发者是优秀的 Flex/Flash 开发者。作为一名 Adobe 认证技术培训师,在过去几年中我培训了许多 Java 程序员,我亲眼见证了 Java 开发者是如何迅速适应 ActionScript 的。作为一名 RIA 项目经理,我发现 Java 开发者不仅能快速掌握 Flex API,而且能正确使用并几乎本能地遵循最佳实践。尽管如此,Java 开发者在学习过程中仍会遇到一些绊脚石。首先,他们处理应用程序的方式发生了范式转变,这些应用程序被 Flash Player 运行时视为“电影”。一般来说,我认为运行时是我的课程进度会放慢、问题会迅速增多的地方。除了运行时,ActionScript 与 Java 或 ActionScript 与 JavaScript 之间还存在一些独特的功能。为了探讨这些差异并阐明 Flash 平台的一些独特功能,我采访了旧金山 Web 开发公司 roundpeg 的首席技术官 Darryl West。
在许多方面,Darryl 代表了我通常在企业培训课程中遇到的 Java 开发者。Darryl 精通 Java,并深入参与开源项目,以及 Spring 和 Hibernate。除了 Java,Darryl 还积极从事 Ruby、Groovy、Grails、Javascript、Ruby on Rails 和 Flex 的不同程度的编程。他从 Java 程序员的角度提供了关于 Flex 的丰富信息,并且在 Java 和 Flex 的后端和前端(包括 Swing GUI 经验)都工作过。他还对数据库工作和多线程环境有丰富的经验。我自己的经验包括培训、开发和管理那些使用 Flash 平台工具、服务器和运行时创建 Flex 应用程序的人。除了是一名专注于 HTML、CSS 和 Javascript 的技术培训师,我还是 Adobe 认证的 Flash 平台讲师。在过去五年多的时间里,我培训了约 2500 名设计师和开发者,他们代表了 700 多家大中小型组织。提供进一步的视角,其中 5 家公司在财富 25 强之列,12 家在财富 100 强之列,21 家在财富 500 强之列。
列表
我采访 Darryl 的结果是列出了 Java 开发者会觉得有用、有趣且有时独特的关于 Flash 平台的十件事。具体来说,这份清单包括 Darryl 在 Flex 开发过程中做出的一些令人高兴的发现,以及他在过程中遇到的一些挑战。这份清单也触及了 Java 开发者为了最有效地使用 Flash 平台可能需要考虑的一些思维上的重大转变。我们似乎也应该包括 ActionScript 和 JavaScript 之间的一些相似点和不同点。清单中的一些主题包括:运行时、数据访问处理,以及 ActionScript 语言的细节,包括闭包、cookie 与共享对象、外部接口类和本地连接类。我们还研究了关于用户界面和 mx 组件与 spark 组件的一些特定的 MXML 特性。
#1:Flash Player 是单线程的

当我告诉我的学生,Flex 运行时,即 Flash Player 是单线程的时,这常常会引起混淆并导致误解。开发者经常会错误地得出结论,认为在其他操作(如视图状态更改或远程过程调用)正在进行时,不能进行新的操作,如搜索尝试。正如 Darryl 所说,“Flash Player 并非真正的单线程,但线程并未暴露。”Darryl 有时会使用各种技术(参见 #10:使用 LocalConnection 类)创建伪线程,如计时器,“但它们不像真正的线程那样运行。”虽然 Darryl 最初对此感到惊讶,但他不认为这是一个严重的问题或缺陷。“……使用 Swing 时,你必须非常注意线程的创建和销毁以及清理……[Flash] 消除了 Java 程序员可能有的担忧,例如如果你开始一个进程,应该将其放在哪个线程上……运行时是多线程的,但程序员没有机会使用这些线程。”
结论:“与 Swing 相比,Flex 应用程序更易于开发和测试。”
#2:一次编写,随处运行

Darryl 重申了我在 Flex 培训课程开始时提出的一个评论。“Flash 运行时真正实现了‘一次编写,几乎随处运行’!”Flash 运行时是跨平台、跨浏览器和跨浏览器版本的。尽管我知道关于帧速率以及 Internet Explorer 与 Firefox 之间存在已知问题,但 Darryl 在他的应用程序中并未遇到任何问题。在这方面,Flex 有助于快速应用程序开发,特别是与 HTML、JavaScript、CSS 应用程序相比,后者需要投入大量时间来测试和修复跨浏览器问题。
结论:“使用 [Flash Player] 时,在不同浏览器中渲染几乎相同。”
#3:一次绘制,然后置之不理

作为一名 Java 开发者,如果你习惯于使用 Java 2D 或编写 Applet,那么每次需要更新时都需要重新绘制。使用 Flex,你只需绘制一次,然后就可以置之不理。API 有许多可以应用的转换——旋转、倾斜、缩放等。据 Darryl 所说,“没有必要循环重绘”,他又一次发现这是一个令人欢迎的变化,也是一个节省时间的功能。
结论:“一次绘制,然后置之不理。”
#4:Flex 对 XML 极其友好

Darryl 认为 Java 对 XML 也同样友好,但他发现 Flex “开箱即用”地对 XML 极其友好,省去了查找和使用 XML 库的步骤。ActionScript 原生支持 EcmaScript for XML(也称为 e4x)。这为 Flex 开发者提供了 DOM 接口的替代方案。e4x 使用更简单的语法访问 XML 文档,将 XML 视为原始类型。效果通常是更快的访问、更好的支持以及程序的数据结构。另一方面,Darryl 发现 Flex 对 JSON 不太友好,并且依赖标准的 AS3corelib 来支持 JSON。
结论:Flex 具有“内置”的 XML 数据交换支持。
#5:Java 项目可能存在类膨胀问题

“虽然 Flex 项目也可能存在类膨胀问题,但程序员受制于运行器。大于 300KB 的 SWF 文件应被视为‘大型’项目,因此应拆分为模块或单独的 SWF。”我请 Darryl 详细说明了这一点以及自定义组件、模块和独立 SWF 之间的区别。“模块与加载它的主 SWF 处于同一空间。独立的 SWF 运行起来就像在另一个浏览器中一样,因此它不会占用主空间中的 SWF。”Darryl 建议开发人员不要尝试使用典型的“Java 结构”,即八到十个选项卡,大量的输入表单等,这些会导致主 SWF 的大小超过 300KB。相反,将主 SWF 拆分为一个单独的项目和 SWF。”他最近从一个主应用程序中剥离了打印功能,并将其拆分到自己的 SWF 项目中。该应用程序有一个包含统计信息的 info 选项卡,也被移到了一个单独的 SWF 中,以及一个用户首选项面板。Darryl 表示,这“不是为了内存,而是为了初始加载时间。”
结论:“重新思考应用程序,以便将不常使用且可以完全独立存在的功能拆分出来。”
#6:Flex 拥有闭包。

Darryl 拥有 Groovy、Ruby 和 Lisp 的背景,他发现了解 Flex 拥有闭包很有帮助,而 Java 程序员则使用内部类。
“每个函数都有一个特殊的 [scope]
属性,它表示函数定义时的环境。如果一个函数从另一个函数返回,那么对旧环境的引用就会被新函数在‘闭包’中捕获。”¹
结论:为了实现面向对象的多态性,可以考虑使用闭包作为继承的良好替代方案.
#7:使用 Spark 实现轻量级组件。

Flex 组件不像 Swing 那样是完整或纯粹的模型-视图-控制器架构。使用 Spark 组件,你必须附加皮肤和滚动条来完成组件。将 mx 与 Spark 组件进行比较时,Spark 类似于 Swing。“Spark 将额外的部分抽离出来……如果你愿意,可以加载它,但不是必须的。”
结论:与 Swing 相比,使用 Spark 构建的 Flex 应用程序可以变得轻量级,并拥有更简单的 API。
#8:浏览器 Cookie 与本地共享对象。

大多数 Javascript 开发者都熟悉 Cookie(也称为 HTTP cookie、网络 cookie 或浏览器 cookie),这是一种包含名称/值对的小型文本文件。Web 服务器通过 HTTP 响应头中的字段将 Cookie 发送到 Web 浏览器,然后浏览器在每次访问该服务器时都会原封不动地将其发送回去。Flash Player 以本地共享对象的形式提供了类似的机制。Flash Player 运行时有一个特定的区域,用于存储由运行时控制和管理的文件。SharedObject 类使用一个名为 getLocal() 的静态、延迟实例化工厂方法,该方法返回 SharedObject 实例,该实例是客户端计算机上本地共享对象文件的代理。开发者将文件名引用传递给 getLocal 方法,如果文件不存在,Flash Player 会创建并打开文件以供应用程序读写。共享对象可以由同一域中的所有 SWF 文件共享。与 Cookie 不同,共享对象是“以机器为中心”且独立于浏览器的,因此使用浏览器 A 存储的对象可以被浏览器 B 读取。
结论:本地共享对象为 Flex 开发者提供了另一个很好的功能,可用于身份验证、存储用户偏好、数据持久化等。
#9:将 GZip 与 ByteArray 结合使用。

像大多数 Java 程序员一样,Darryl 深入研究了 API 中的相关类。在研究 ByteArray 类(ByteArray 类提供了优化二进制数据读写和处理的方法和属性)时,他发现了将 gzip 与 ByteArray 类的 compress 和 decompress 方法结合使用的机会。虽然许多 Flex 开发者倾向于使用 Action Message Format (AMF) 对象序列化来从服务器传输数据到客户端,但 ByteArray 类支持 zlib 压缩和解压缩。gzip 不属于 AMF,而且由于它是二进制的,所以压缩效果不佳,这也是不使用 AMF 的一个论据——二进制比 XML 或 JSON 文本小,但不如压缩后的 XML/JSON 小。此外,XML/JSON 具有跨平台和跨语言特性,因此比 AMF 更具可移植性。根据 Darryl 的说法,AMF 的最佳替代方案是 HTTPService,但 HTTPService 是非二进制的,所以你不能直接使用 gzip,你还必须进行 base64 编码。这会增加压缩数据的大小,因此使用 gzip 和 base64 编码的 XML/JSON 的典型净压缩率约为 45% 到 50%。这与使用 AMF 大致相同,但你可以通过 XML/JSON 获得可移植性(以及更简单的测试)。
存在许多网站演示了使用 5,000 到 100,000 行或更多数据进行的基准测试。然而,我所参与的大多数网络应用程序每页返回的记录数量要少得多。Darryl 还报告说,在更真实的行数上,压缩效果优于在 100,000 多行上进行压缩,从而实现了不仅超越 AMF 的性能,而且还消除了对 BlazeDS 或 LiveCycle 的需求。
结论:对于远程处理,考虑在服务器端使用 gzip 压缩的 XML 或 JSON 包,并在客户端使用 ByteArray 进行压缩/解压缩。
#10:使用 Local Connection 类

另一个有用的类是 LocalConnection 类,用于促进浏览器间的 SWF 通信。这类似于 Java 在同一域中的 Applet 到 Applet 通信。Darryl 发现这个类的一个用途是通过使用本地连接提供 SWF 到 SWF 的通信来克服多线程的不足,即使在两个独立的浏览器之间也能实现。特别是有一个应用程序加载主 SWF,而一个弹出窗口或独立的浏览器通过本地连接的消息传递与主 SWF 通信。
结论:Flex 应用程序提供了一种类似于 Applet 的模块到模块通信方式,但将这种能力扩展到跨/独立浏览器。
¹ Caswell, Tim. 学习带对象图的 Javascript。2010 年 9 月 30 日
<http://howtonode.org/object-graphs>
Darryl West 是 roundpeg 的首席技术官,这是一家位于旧金山的软件开发公司,专注于为网络、无线和交互式电视领域开发动态、数据驱动的应用程序。我们对未来的愿景是拥抱下一代支持网络的设备的新媒体应用架构。