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开发的关键之一是使用模块和运行时共享库(RSL),它们的好处包括从系统不同部分的并行开发到客户端上更有效的内存管理。 另一个关键是利用Spring BlazeDS集成,该集成大大简化了服务器端开发以及与后端各种技术的集成,例如与Java Messaging Service(JMS)和Spring Security的消息传递。
以下是Flex开发的关键:
- 利用Flex的差异。 了解为什么Flex开发不同于典型的Web开发,并利用这些差异使您的应用程序受益。
- Flex模块。 了解Flex模块以及如何模块化Flex开发和部署。 使用Flex模块解耦项目的不同层。
- 了解反模式和模式。 预先了解适当的应用程序反模式,以便您可以按照适当的体系结构模式实施良好的设计。
- 通过Spring BlazeDS集成项目简化开发。 通过Spring BlazeDS集成项目简化Java服务器集成。
- 有效设计。 与您的设计团队紧密合作,以充分利用Flex和Adobe Flash的优势。
- 测试。 预先计划测试。
是什么使Flex的Web开发与众不同?
与传统的Web应用程序不同,Flex应用程序的开发更像传统的桌面应用程序。 例如,根据应用程序的结构,整个Flex应用程序都将下载到客户端(可能是较大的下载量)。 但是,有许多技术可以帮助优化此过程,例如使用组件库并将项目分解为模块。
这种方法不同于传统的超文本标记语言(HTML)应用程序-甚至是使用Ajax开发的应用程序。 HTML网站通常分为不同的页面,因此下载量很小。 即使使用Ajax,下载大小仍然相对较小,因为大多数Ajax库本身都相对较小。 与下载整个应用程序相比,这种低调使得单个页面的整体大小较小。
Flex与传统Web应用程序开发之间的另一个区别是状态主要由客户端维护。 这超出了向Web应用程序添加Ajax控件的范围,Ajax控件通常仅在Web浏览器中维护少量客户端状态。 现在,应用程序的整个状态都保存在局部变量中。
如果您不熟悉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应用程序使用的类和其他资产。
- 主题。 主题定义应用程序的外观,由主题的资产(例如图像文件和字体)以及级联样式表(CSS)组成,级联样式表(CSS)定义了如何将它们应用于应用程序。
- 资源包。 这些是本地化的属性文件和Adobe ActionScript类的集合。
将SWC包含在项目中的方法有两种:您可以静态链接到它们,在这种情况下,它们将被编译到您的项目中,或者可以将它们用作RSL。 使用RSL的优点是可以将它们分别下载并缓存在客户端上。 另外,如果客户端具有多个模块,则它们都可以共享相同的RSL。
您还可以模块化主应用程序。 一种方法是使用Flex模块。 另一个是通过使用子应用程序。 子应用程序的优点是可以独立于主应用程序进行开发和测试。
请注意,在编译模块和库时,Flex编译器不会像Java中那样以分层方式遍历树。 相反,它仅基于链接到主应用程序的内容进行编译。 此行为会使开发模块和库变得棘手,因为您可能不知道没有链接文件。在开发库时,必须定义要包括的文件。
模块具有相对简单易用的优点。 本质上,您将要加载的模块的URL传递给Flex模块管理器:
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加载模块以维护关键的业务功能。
使应用程序易于开发和测试
通过启用适当的视图堆栈,您可以使用单个URL轻松到达应用程序中的任何位置,此功能具有超越单纯的可用性的优点。 它还使使用该应用程序更加容易。 一个常见的问题是,当您需要更改需要浏览多个屏幕和表单的应用程序部分时。 如果您必须为每个更改手动导航,那么此过程可能很耗时。 相反,使用固定的URL访问应用程序的不同部分可以极大地减轻开发过程中的麻烦并加快处理过程。 这种相同的模式还使应用程序更易于测试,因为它使应用程序的各个部分可以通过URL访问和测试。
使用Flex,有两种方法可以将视图堆栈构建到应用程序中。 一种使用状态,另一种使用视图堆栈组件(ViewStack.mxml)。 视图堆栈只是显示对象的堆栈:它们可以是包裹简单显示表单或复杂组件的画布。 视图堆栈的好处是,您可以通过设置当前子代轻松地从代码中操纵它们。 例如,myViewStack.selectedChild = accountInfo会将视图堆栈设置为显示accountInfo视图。 此功能使您可以轻松地操作视图堆栈以进行测试和开发。
客户端体系结构:反模式
在软件编程中,一个常见的范例是定义软件开发的反模式和模式。 模式是常见问题的可重复解决方案; 反模式是程序员刚接触某种语言时最常犯的错误。 通过定义Flex的模式和反模式,我展示了Flex程序员新手犯的一些最常见的错误,然后展示了为Flex编程开发的一些最佳实践。 这些做法可帮助您避免常见的陷阱,从而有助于项目大规模发展。
第一个常见的反模式是将所有MXML视图放在根包中。 不太明显的是,您可以将MXML文件放置在包中,并通过它们的名称空间来引用它们,这是可能的,因为实际的包名称未在文件中明确命名。 在幕后发生的事情是,MXML文件根据其所在的目录结构放入一个包中。因此,将MXML文件保留在根包中等同于不将它们放在任何包中,否则会造成混乱较大的项目。
例如, Flex Store Sample不仅将主应用程序文件放在根包中,而且还将主页,产品和支持(HomeView.mxml,ProductsView.mxml,SupportView..mxml)都放在根包中。 这类似于将所有视图包放在Java包的根目录中。
开发人员在创建第一个应用程序时面临的一个常见问题是如何将应用程序模型与视图关联。 常见的反模式是在类之间传递模型或要求在调用视图之前对其进行设置。 同样是反模式的一个示例(同样来自Flex商店)是在主应用程序中,目录传递到ProductsView中:
<ProductsView id="pView" label="Products" catalog="{catalog}"
该代码适用于小样本,但是随着应用程序的扩大,它会产生问题,例如各层之间的紧密耦合,并且使开发和测试变得困难。 发生的另一个问题是,当需要在应用程序的不同部分中显示相同的数据时,必须将数据分别传递给每个组件。 最初,这似乎不是问题,但请想象一下,尝试模拟每个传递和使用数据的实例。
客户端体系结构:推荐模式
这些年来,为Flex开发了许多架构和框架。 最有前途的应用之一是使用像Swiz这样的轻依赖注入框架来分离项目结构。 使用Swiz,您可以定义类似于Spring的应用程序bean,这些应用程序bean被注入到应用程序的不同部分中。 然后,典型的应用程序结构将包含一个定义服务如何连接在一起的中央类,例如,一个ClientBeans.mxml类,它声明该应用程序的通用模型和控制器:
<model:StoreModel id=”storeModel” />
然后将视图类连接到控制器:
[Autowire (bean="storeModel")]
[Bindable]
public var storeModel: StoreModel;
然后,您可以对控制器和其他常见组件执行相同的操作。 以这种方式布置项目结构有许多优点。 其一是它允许将模拟服务轻松插入控制器中,从而促进了开发和测试。 另一个优点是,它消除了客户端体系结构的不同层之间的耦合。
设计良好的主视图状态有助于实现前面提到的可用性和可测试性目标。 视图堆栈的想法是使应用程序中的任何视图都可以通过单个URL访问。 此外,视图堆栈的参数需要通过公共控制器传递,这使您可以在整个应用程序中使用具有所需视图和必要参数的公共URL。
一个Flex体系结构示例:重构视图存储
作为该架构的示例,让我们逐步完成将在http://www.adobe.com/devnet/flex/samples/flex_store/上找到的Flex Store样本重构为合适的架构的第一步。
首先,将主要源代码移到子文件夹中。 在此示例中,我将所有资产,productsView和samples目录移至flexstore / src / flex作为主要源代码目录。 我还将所有MXML和CSS文件都移到了该目录中。
接下来,将三个主要视图类移动到视图目录中。 在src / flex目录下,创建com / anvilflex / view目录。 在此目录中,放置HomeView.mxml,ProductsView.mxml和SupportView.mxml文件。 为此,必须对flexstore.mxml进行以下更改:
- 将
xmlns:view="com.anvilflex.view.*"
到<mx:Application>
标记。 - 更改视图以使用
<view>
标记(因此<HomeView>
将变为<view:HomeView ... />
)。
将Product.as
类移动到名为domain-com / anvilflex / view的单独文件夹中。 为此,您必须修复Product
类的import
语句。 在Flash Builder中解决这些问题的最简单方法是删除现有的import
语句,然后删除Product
字词的最后一个字母。 然后,按Ctrl-空格键使用自动完成功能,这还会为Product
类添加正确的导入。
最后,引入ProductControl
来管理产品页面和结帐之间的转换。
通过Spring BlazeDS集成简化Java开发
Spring BlazeDS集成项目极大地简化了与客户端交互的Java服务器代码的开发。 使用该项目的最新版本,一个团队成员可以实现核心配置文件,例如web.xml和Flex服务配置文件。 然后,团队成员只需要了解如何在其类上添加适当的注释,即可将其作为BlazeDS的服务公开。 作为一个简单的示例,您可以将Product Service
类公开为远程服务:
@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将单个方法公开为远程方法。 在后台,这些方法作为Flex可以通过远程对象调用的远程服务向BlazeDS公开。
与图形设计团队合作
新的Flex项目的一个常见问题是确保图形设计团队了解Flex中的功能。 Flex为有趣的设计提供了许多可能性:图形设计团队需要了解什么是可能的,以及Flex如何代表基本的设计转变。
通常,挑战在于图形设计团队使用Adobe Photoshop之类的工具创建模型。 尽管设计看起来不错,但距离正常工作的应用程序还有很长的路要走。 必须削减设计,并在应用程序CSS中匹配颜色和字体。 另外,根据设计的复杂性,需要创建自定义Flex组件。 这些组件可能像具有自定义外观的按钮一样简单,也可能与定义一组新功能的组件一样复杂。 此过程的挑战在于,在设计和实现之间进行转换,找出可能的结果以及从设计中实施更改可能非常耗时。 每次迭代都会变得更加复杂。
幸运的是,Adobe引入了一种称为Flash Catalyst的新工具来帮助完成此过程。 它允许将诸如Photoshop之类的工具中的图稿轻松转换为可用的原型。 它还可以用于创建原型GUI,最终可以将其用于最终应用程序中。 通过使用此工具,设计人员可以更快地迭代其设计,从而使组织可以更有效地调整设计以满足其要求。
单元和功能测试
通过Flex开发,有两种主要的方法来测试应用程序。 首先是使用funit
或fluint
功能测试。 此方法允许测试服务和控制器。 第二种方法是功能测试,它可以测试与GUI的实际交互。 功能测试可以使用商业工具(如Mercury)或开源工具(如FlexMonkey)。
他们对任何一种测试的关键都是在可以独立测试的松散耦合层中创建代码。 例如,可以通过更改默认连线以使用模拟服务来轻松模拟服务。
结论
具有Spring BlazeDS的Flex集成为大型企业应用程序提供了一套出色的技术。 开发人员面临的挑战在于设计架构,使其具有模块化,易于测试和可扩展的特点。 通过可扩展性 ,我不仅指软件,还指开发过程。 预先解决挑战可以帮助使项目成功,并为组织带来更高的投资回报率。