`
gongstring
  • 浏览: 588059 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

高效率的超大规模Flex开发

    博客分类:
  • Flex
阅读更多

Adobe Flex开发与传统的Web开发有很多不同之处。正确的理解和利用这些不同之处,可以帮助我们创建更丰富的用户体验,也可以反过来增加网站的可用性以及浏览和更新速度。Flex还提供了大量的组件和技术库来让Web开发更加轻松——它提供的强大工具要远远超过传统Web 2.0中的异步JavaScript和XML(Ajax)应用。此外,Adobe公司最近发布的Adobe Flash Builder 4 beta(以前叫Adobe Flex Builder)中提供了许多新的和改进的工具,他们可以用来开发大规模的Flex应用程序。Flash Builder 4着重于提高开发人员的生产力以及设计人员和开发人员的工作流。

Flex开发中的关键要素之一是使用模块和运行时共享库(Runtime Shared Libraries,RSLs),这些模块和库可以方便系统不同部分的并行开发以及客户端上高效的内存管理等等。另外一个关键要素是使用Sprint BlazeDS集成,它大大简化了后台不同技术服务器端的开发和集成,如使用Java消息服务(JMS)和Spring安全进行的通信。

以下是Flex开发中的一些关键要素:

  • 利用Flex的不同之处。了解为什么Flex开发与传统Web开发有所不同,并利用那些不同之处让应用程序从中获益。
  • Flex模块。了解Flex模块以及怎样模块化Flex开发和部署。使用Flex模块来解耦项目中的不同层次。
  • 了解反模式和模式。 预先了解正确的应用程序反模式,这样你可以按照正确的架构模式实现优秀的设计。
  • 使用Spring BlazeDS集成项目简化开发。使用Spring BlazeDS 集成项目简化Java服务器集成。
  • 有效地设计。与设计团队紧密合作,充分利用Flex和Adobe Flash的优势。
  • 测试. 预先计划测试。

是什么让Web开发与Flex有所不同?

与传统Web应用程序不同,Flex应用程序开发更像传统的桌面应用开发。例如,整个应用程序会被下载到客户端——这是一个庞大的下载,而且取决于应用程序如何组织。当然,有许多方法可以优化这个过程,例如使用组件库或将工程分解成各个模块。

这套方法与传统的超文本标记语言(Hypertext Markup Language,HTML)编写的应用程序不一样——即使它是用Ajax开发的。一个HTML的Web站点通常可以划分成不同的页面,以使得下载量非常小。并且即使使用Ajax,下载量还是相对较小,因为大部分Ajax库本身就相对较小。使用这种方法可以让单个页面的下载量比整个应用程序更小。

Flex与传统Web应用程序开发的另外一个不同之处在于,状态主要在客户端上维护。这超出了在Web应用程序上使用Ajax控件,因为后者一般只在Web浏览器上维护少量的客户端状态。而现在,应用程序中的所有状态都在局部变量中进行维护。

如果你还不太熟悉Flex的话,另外一个不同之处可能对于你来说是一个挑战。Flex使用了一个高度的事件驱动编程风格,主要原因是Adobe Flash Player是单线程的,因此任何需要长时间运行的调用都需要注册一个回调函数。单线程对于图形化用户界面(GUI)开发来说是有利的,因为它不存在死锁或者一个线程窃取所有CPU周期,从而保持了GUI的响应。单线程还使得开发更加简单,因为你不需要处理多线程编程。(还记得在Swing中处理线程的噩梦吗?)

Flex中用以处理事件的主要机制是函数指针,或者作为函数参数进行传递的闭包。这些指针可以是用户为了某个异步事件结束时发生的事件或者提醒而注册的。(函数指针对于Java程序员来说很有挑战,因为核心Java语言还不支持闭包。)

Flex模块至关重要

Flex提供了一些选项可以将应用程序划分成模块,包括创建库以及主应用程序的子模块。通过将项目设计成层次化的形式,开发和编译都可以在单个的分支中进行。

模块化Flex项目的主要好处在于,这么做可以优化客户端上下载和启动的时间。应用程序的一小部分可以预先下载到客户端,而剩下的部分可以在后端按需很进行加载。此外,模块还可以被加载和卸载,以减少客户端上的内存占用量。

模块化Flex项目的另一个主要好处是,它可以让开发过程更容易模块化。它允许开发人员在不同的模块和库上进行工作以避免开发团队的死锁发生。

然而构建大型Flex应用程序的一个挑战之处在于,编译过程所花的时间要比大部分程序员熟悉的Java编译时间要慢很多。重新编译一个大型Flex应用程序可以花上好几分钟。想要优化这个过程,你可以创建分离的库并且只编译你当前工作的应用程序部分。

一种方法是采用SWC文件形式的库。SWC是Flex中使用的主要存档格式,它有点类似于Java中的Java存档(JAR)文件。你可以使用SWC档案来完成一些工作:

  • 组件库。 组件库是一个SWC文件,它包含Flex应用程序中使用的类和其他资源。
  • 主题。主题定义了应用程序的观感。它包含主题所需的资源(例如图片文件和字体),以及定义这些资源如何被使用在应用程序中的层叠样式表(Cascading Style Sheet,CSS) 。
  • 资源包。这些都是本地化的属性文件和Adobe ActionScript类集。

有两种方法可以在项目中添加SWC文件:要么静态地连接它们,这种情况下它们会编译进你的项目;要么把它们当做运行时共享库(RSL,Runtime Shared Library )来使用。使用多个RSL的好处在于它们可以被分开下载和缓存到客户端上。此外,如果客户端有多个模块的话,它们还可以共享同样的RSL。

你还可以将主应用程序进行模块化。一种方式是采用Flex模块;另一种是使用子应用程序。子应用程序的好处在于它们独立于主应用程序进行开发和测试。

注意当编译模块和库时,Flex并不像Java一样层次地遍历整个树。相反它只编译链接到主应用程序中的部分。这种方式会使得模块和库的开发非常微妙,因为你可能注意不到某个文件被链入了。当进行库开发的时候,有必要定义哪些文件会被包含。

库具有相对直接的可被利用的优势。本质上你是向Flex模块管理器传递了想要加载模块的URL。

    protected function getModuleFromServer(url:String, onSuccess:Function) :void
    {
       var module:IModuleInfo = ModuleManager.getModule(url);
           module.addEventListener(ModuleEvent.READY, loadModuleSuccessHandler);
            module.load();
    }

    public function loadModuleSuccessHandler(moduleEvent:ModuleEvent) :void {
        var module:IModuleInfo = moduleEvent.module;
	  .... handle initializing the module
    }

像这样进行模块加载的有趣之处在于你可以指定另一个URL来加载这个模块——例如,在某个故障情况下,客户端丢失了与主服务器的连接。这时客户端可以继续从另外一个URL中加载模块,以维护重要的业务功能。

让应用程序轻松地开发和测试

通过适当地激活View栈(Stack),你可以用单个URL轻松地访问应用程序的任何点——这一功能拥有超越单纯可用性上的优势。除此之外它还使得应用程序上的工作变得很轻松。一个常见的错误发生在你改动部分应用程序,而这个应用程序需要在好几个屏幕和样式中进行导航。如果你不得不为每一处改动而手工进行导航时,这个过程将非常耗时。取而代之,我们可以使用一个固定的URL来访问应用程序的不同部分,这将大大减轻开发中的痛苦并且加速整个过程。相同的模式同样可以让应用程序变得很容易测试,因为应用程序单个部分可以通过URL来访问和测试。

在Flex中,有两种方法可以将视图栈构建到应用程序中。一种方法是使用状态(states),而另一种方法则是使用一个ViewStack组件(ViewStack.mxml)。视图栈只是用来显示对象的栈:这些对象可以是一个包装简单的表格或是一个复杂组件的画布(canvas )。使用视图栈的好处在于你可以通过在代码中设置当前的子组件来轻松的操作它们。例如 myViewStack.selectedChild=accountInfo 将会设置视图栈去显示accoutInfo视图。这个功能可以让你在测试和开发中轻松地操作视图栈。

客户端架构:反模式

在软件编程中,会有一个通用的范式来定义软件开发中的反模式和模式。模式是解决常见问题的重复解决方案;反模式则是不熟悉语言的程序员最会发生的常见错误。定义好Flex中的模式和反模式后,我将会展示一些新手Flex程序员常犯的错误,然后再展示一些Flex编程开发的最佳实践。

这些实践可以帮助项目在增长为大规模的过程中,避免常见的错误。第一个通用的反模式是将所有的MXML视图放在根包中。这么做的好处不是很明显,因为你可以将MXML文件放入到包中,并且通过它们的名字空间(由于实际的包的名字可能没有在文件中指定)进行引用。其实MXML文件是根据其所在的目录结构来放入包当中的。因此将MXML文件放入到根包中等价于不将它们放入任何包中,这样做会使一个大型项目变得一团糟。

举一个例子,Flex商店示例不仅将主应用程序文件放入到根包中,还将主页,商品页和支持页(HomeView.mxml, ProductsView.mxml, SupportView..mxml)都放入根包中。这个过程和把所有根目录中的视图包放入一个Java包中比较类似。

开发人员在创建第一个应用程序时常常会碰到一个问题:那就是如何用视图来捆绑住应用程序模型。一个通用的反模式是在类之间传递模型或者在调用视图前设置模型。反模式的一个例子——也来自于Flex商店——即在主应用程序中将目录传递进ProductsView。

<ProductsView id="pView" label="Products" catalog="{catalog}" 

这段代码在小的例子中可以正常工作,但是随着应用程序逐渐变大,它会带来一些问题,如层之间的紧耦合,以及很难开发和测试。另外一个问题是当同样的数据需要在应用程序不同部分显示时,这些数据需要分开地传递给每一个组件。首先,这看起来似乎不是一个问题,但是试想下如果尝试模拟每一个传递和使用数据的实例,结果会怎样。

客户端架构:推荐模式

多年来众多的Flex架构和框架已经被开发出来。最有前景的一种方法使用了一个像Swiz一样的轻量级依赖注入框架,并用它来划分项目结构。你可以在Swiz中定义类似于Spring中的应用程序bean,并将它们注入到应用程序中的不同部分。一个典型的应用程序框架会包含一个中心类,这个类会定义服务怎样组合在一起——例如,ClientBeans.mxml 类为应用程序声明了通用的模型和控制器:

<model:StoreModel id=”storeModel” />

然后View类连接上控制器:

[Autowire(bean="storeModel")] 
[Bindable] 
public var storeModel: StoreModel; 

对于控制器和其他通用组件,你也可以这么做。用这种方式组织项目结构有一些优势。一个优势在于它可以让模拟服务轻松地植入控制器,以促进开发和测试。另外一个优势在于它能够除去和客户端架构不同层之间的耦合性。

一个精心设计的主视图状态有助于实现前面提到的可用性和可测试性目标。视图栈的思想是让应用程序中的任何视图可以通过单个URL进行访问。除此之外,视图栈的参数需用通过通用控制器传入,这个通用控制器能够让你在应用程序中各个地方使用通用的URL和必要的参数来访问期望的视图。

一个Flex架构示例:重构View Store

作为架构的一个示例,让我们先看看怎样将http://www.adobe.com/devnet/flex/samples/flex_store/ 上的Flex Sotre的例子进行重构。

首先,将主源代码移动到子目录中。在这个例子中,我将所有的资源,产品视图,以及样例目录移动到了flexstore/src/flex中并将其作为源代码主目录。我还把所有的MXML和CSS文件移动到了这个目录中。

接下去,将三个主视图类移动到视图文件夹中。在src/flex目录下创建一个com/anvilflex/view目录。将 HomeView.mxml,ProductsView.mxml以及SupportView.mxml文件放入到这个目录中。为此,你必须对 flexstore.mxml做出如下改动:

  • 在<mx:Application>标签中加入xmlns:view="com.anvilflex.view.*" 。
  • 将视图变为使用<view>标签(因此<HomeView>将变成<view:HomeView ... />)。

将Product.as类移动到分开的域文件夹中——com/anvilflex/view。为此,你必须修复Product类的import 语句,并删除Product单词的最后一个字母。接下去,按住Ctrl-空格键来使用自动完成功能,它同样也可以为Product类加入正确的 import语句。

最后,引入ProductControl来管理产品页面和结算间的过渡。

使用Spring BlazeDS集成简化Java开发

Spring BlazeDS集成项目大大简化了与客户端交互的Java服务端代码开发。在最新发布的项目中,团队成员可以实现核心的配置文件,如web.xml以及Flex服务配置文件。接下去,团队人员需要简单地了解一下如何在他们的类中增添适当的标注来将它们作为服务展现给BlazeDS。举个简单的例子,你可以将Product服务类展现为一个远程服务:

	@Service("productService")
	@RemotingDestination(channels={"my-amf"})
	public class ProductDAO {

	@Autowired
	public ProductDAO() {
		//... initialize the ProductDao class
	}

	@RemotingInclude
	public Product findProductName(int id) {
		Product product = database.findProduct(id);
		return product.name;
	}

在这个例子中,我将ProductDAO类声明为了远程服务,它可以通过使用productService进行调用。单个方法可以使用 @RemotingInclude将其展现为远程方法。其实这些方法都会作为远程服务展示给BlazeDS,其中Flex可以通过远程对象调用远程服务。

与图形设计团队一起工作

刚开始的Flex项目中一个常见的问题是,确保图形设计团队了解Flex中可以做什么。Flex为很多有趣的设计提供了可能性:图形设计团队需要了解Flex中可以做什么,以及Flex怎样来表示一个基础设计转变。

通常情况下,碰到的问题是,图形设计团队用一些像Adobe Photoshop的工具创建了一个模拟。尽管设计看起来非常好,但是它与工作中的应用程序还相距甚远。整个设计将不得不削减并且颜色和字体都得与应用程序的CSS相匹配。根据设计的复杂度,自定义的Flex组件也需要被创建。这些组件可能是需要自定义皮肤的按钮,也可能是定义了一系列新功能集合的组件。困难之处在于设计和实现之间变得极其耗时,设计人员需要搞清楚什么是可能的并从设计中实现这些变化。每一次迭代都会变得更加复杂。

幸运地是,Adobe已经引入了一个新的工具来改进这个过程,这个工具就是Flash Catalyst。它可以让类似Photoshop这样工具产生的艺术品能够轻松地转变为可用的原型。它还可以创建一个原型的GUI并最终应用到应用程序中。通过使用此工具,设计人员可以更快地遍历他们的设计,从而使该组织能更有效地调整设计,以满足其要求。

单元及功能测试

Flex开发中有两种主要的方法来测试一个应用程序。第一个是使用funit或者fluint的功能测试。这个方法可以进行服务以及控制器的测试。第二个方法是功能测试,它可以测试与GUI间的实际交互。功能测试可以使用像Mercury一样的商业工具,或者像FlexMoneky一样的开源工具。

两种类型测试的关键是要在松耦合层创建可以独立测试的代码。例如可以通过将默认捆绑改变为使用模拟服务,来轻松地修改服务。

总结

使用Spring BlazeDS集成的Flex为大规模企业应用程序提供了一系列卓越的技术。开发人员的挑战在于设计模块化,易调试,可扩展的架构。这里的可扩展,我指的不仅仅是软件,还包括开发过程。解决这些挑战可以帮助项目成功,并为组织带来一个更高的投资回报率。

查看英文原文:Super-sized Flex Development—Without the Extra Calories


译者介绍:曹如进,计算机软件与理论专业硕士研究生,主要研究方向包括算法设计与分析,语义网。目前对函数式编程语言,富客户端开发比较感兴趣。InfoQ中文站内容团队,尤其是架构、SOA和Ruby社区需要您的参与,有意者请邮件至editors【AT】cn.infoq.com

分享到:
评论

相关推荐

    Java_Flex,Java_Flex,Java_Flex

    Java_Flex技术结合了Java的强大后端...总的来说,Java_Flex的集成为开发者提供了构建高性能、高交互性的Web应用的途径。通过恰当的集成策略和技术选择,我们可以充分利用两者的优点,创造出既美观又实用的应用程序。

    flex java开发

    这些技巧对于提升大规模Flex应用的运行效率至关重要。 最后,本书可能还会讨论一些高级主题,如使用Flex和Java进行移动应用开发,或者利用AIR(Adobe Integrated Runtime)创建桌面应用程序。这些内容将帮助开发者...

    flex开发系列书籍:WebGIS框架设计与实现

    文章中提到了一个具体的公众信息服务系统案例,通过应用基于Flex的WebGIS框架,系统不仅提升了运行效率,还显著增强了用户体验,为大规模空间信息的发布和管理提供了强有力的技术支撑。这一实践证明,基于Flex的...

    Enterprise Development with Flex.pdf

    企业级开发通常涉及复杂的业务逻辑、大规模的数据处理、高可用性和安全性需求。Flex框架通过提供强大的数据绑定、事件处理机制以及对各种数据源的支持,能够有效应对这些挑战。此外,Flex还支持跨平台部署,可以构建...

    Flex游戏开发进阶篇

    在Flex游戏开发中,利用AS3.0与Flash平台结合物理引擎能够实现更加逼真和丰富的游戏体验。 #### 物理引擎实现: - **刚体碰撞检测**:通过计算物体间的相互作用来模拟碰撞效果。 - **动力学系统**:模拟物体运动...

    Flex3.0RIA开发详解电子教程14

    通过学习“Flex3.0 RIA开发详解电子教程14”,开发者不仅可以掌握Flex的基本用法,还能深入理解其高级特性和最佳实践,从而开发出高质量、高性能的RIA应用。文件“flex14”可能是该教程的第14部分,可能涵盖了上述的...

    flex文档

    这一阶段,RIA开始崭露头角,以其高效率和低成本的特点获得青睐。 - **Rich Internet Application (RIA)**:结合了桌面应用程序的快速响应和Web应用的广泛覆盖优势,成为新一代的网络应用范式。 #### 三、...

    flex学习资料ppt

    2. **Adobe Flex Builder**:基于Eclipse的集成开发环境(IDE),为Flex开发提供了可视化设计界面和代码编辑器,提高了开发效率。它支持MXML和ActionScript的智能编码,并且提供调试和测试功能。 3. **Adobe ...

    flex和hibernate的整合

    通过AMF,这些调用可以以低延迟和高效率完成,因为AMF能将复杂的对象序列化为二进制格式。 5. **错误处理和事务管理**:在整合过程中,需要考虑错误处理和事务边界。Flex客户端需要捕获并处理可能出现的服务器端...

    Flex与Java整合

    这种方式的核心思想是将Java和Flex整合到同一个项目中,使得开发过程更加紧密,提高了协作效率。具体步骤如下: 1. **新建Flex项目**: - 切换到Flex视图,创建一个新的Flex项目。 - 指定Java源码存放位置,即...

    工资管理系统(flex版)

    本文将深入探讨一个基于Flex技术与ASP.NET开发的工资管理系统,该系统以其美观的界面和稳定的性能,为用户提供了卓越的使用体验。 工资管理系统是企业管理中的重要组成部分,它能够自动化处理员工的薪资计算、发放...

    AgentsFlex是一个优雅的LLM应用程序框架,类似于Java的LangChain.zip

    3. **高性能**:框架优化了计算效率,确保在处理大规模语言数据时保持高效率,这对于处理实时或大数据量的语言任务至关重要。 4. **可扩展性**:AgentsFlex支持多线程和分布式计算,方便开发者构建可扩展的应用,...

    Java整合flex的web小项目

    2. **MySQL**: MySQL是一款开源、高性能的关系型数据库管理系统,适用于中小规模的Web应用。在本项目中,Java通过JDBC(Java Database Connectivity)API与MySQL通信,执行SQL语句进行数据操作。你需要设置数据库...

    专题资料(2021-2022年)FLEX提高编译效率解决方案.docx

    4. **使用 YLZPlugin 插件**:安装此 Eclipse 插件后,开发者可以直接在 Flex 模块上右键选择“编译 Flex 模块”,简化编译步骤,且效率较高,无需每次修改都修改 ant 文件。 三、编译效率测试 在特定的硬件配置...

    flex3企业级web应用系统设计与实现

    《Flex3企业级Web应用系统设计与实现》这本书深入探讨了使用Adobe Flex技术构建高效、交互性强的企业级Web应用程序的方法...对于想要从事Flex开发或者希望提升现有Flex项目质量的人来说,这本书是一份宝贵的参考资料。

    flex与后台交互的常用四种方式

    Flex作为一个强大的富互联网应用程序(RIA)开发框架,与后台服务器的交互是其核心功能之一。本文将详细探讨Flex与后台交互的四种常见方式:HTTPService、WebService、RemoteObject和URLLoader,以及它们各自的特点...

    flex+asp.net+access

    HTTP服务允许Flex客户端向ASP.NET服务器发送XML或JSON格式的数据,而AMF是一种二进制格式,效率更高,常用于处理大量数据或需要高性能交互的场景。在GuestBook应用中,当用户在Flex前端提交留言时,数据会被封装成...

Global site tag (gtag.js) - Google Analytics