Flex模塊化開發(fā)優(yōu)勢及技巧解析
本文和大家重點(diǎn)討論一下Flex模塊化開發(fā)的概念,模塊可以讓你將程序分割成幾個(gè)片段或單元。主程序或“殼”,可以動(dòng)態(tài)的加載其它需要的模塊,不會(huì)在啟動(dòng)時(shí)加載所有的模塊,也不會(huì)加載任何用戶尚未進(jìn)行交互的模塊。
Flex模塊化開發(fā)
模塊是可以被一個(gè)程序加載和卸載的SWF文件。模塊不能獨(dú)立于程序運(yùn)行,但是可以在任意數(shù)量的程序間共享。
模塊可以讓你將程序分割成幾個(gè)片段或單元。主程序或“殼”,可以動(dòng)態(tài)的加載其它需要的模塊,不會(huì)在啟動(dòng)時(shí)加載所有的模塊,也不會(huì)加載任何用戶尚未進(jìn)行交互的模塊。當(dāng)程序不再需要一個(gè)模塊時(shí),可以卸載模塊來釋放內(nèi)存和資源。
Flex模塊化程序有如下優(yōu)點(diǎn):
1.更小的初始階段SWF文件下載量;
2.更短的加載時(shí)間
3.更好的封裝程序的相關(guān)方面
模塊的好處
模塊是包含了一個(gè)IFlexModuleFactory類工廠的可動(dòng)態(tài)加載的特殊類型的SWF。它允許一個(gè)程序在運(yùn)行時(shí)加載代碼并創(chuàng)建類實(shí)例,而不需要類實(shí)現(xiàn)被鏈接到主程序。
模塊與運(yùn)行時(shí)共享庫(RSLs)的共同點(diǎn)在于都從程序中將代碼分割到獨(dú)立加載的SWF文件中。但模塊比RLS更加靈活,因?yàn)槟K可以在運(yùn)行時(shí)動(dòng)態(tài)的加載、卸載,且在程序外被編譯。
兩個(gè)常見的使用模塊的場景是有著不同的用戶路徑的程序和一個(gè)門戶(portal)程序。
模塊API細(xì)節(jié)
模塊通過一個(gè)標(biāo)準(zhǔn)接口實(shí)現(xiàn)了一個(gè)類工廠。類工廠的產(chǎn)品實(shí)現(xiàn)了一個(gè)被“殼”所感知的接口,或“殼”實(shí)現(xiàn)一個(gè)可以感知模塊的接口。
通過使用公共接口定義,這些共享的接口可以減少“殼”與模塊之間的硬依賴。這提供了類型安全的通訊,以及不會(huì)增加SWF文件長度的強(qiáng)制的抽象層。
下圖展示了“殼”和模塊的接口之間的關(guān)系:
ModuleManager管理被夾在的模塊的集合,這些模塊被加工為以模塊URI為索引的單例的Map。加載一個(gè)模塊將觸發(fā)一系列事件使客戶端可以監(jiān)視模塊的狀態(tài)。模塊總是只加載一次,但是之后的重加載還是會(huì)導(dǎo)讀事件,所以客戶端代碼可以被簡化,并且可放心的通過READY時(shí)間來感知模塊的類工廠是否對用戶可用。
ModuleLoader類是位于ModuleManagerAPI頂部的“薄層”(thinlayer)。ModuleLoader類是用于實(shí)現(xiàn)基于模塊架構(gòu)的最簡單的類,而ModuleManager則提供了對模塊更全面的控制。
模塊的域
默認(rèn)的,一個(gè)模塊被加載進(jìn)當(dāng)前程序域的一個(gè)子域。你可以通過ModuleLoader類的applicationDomain定義一個(gè)不同的程序域。
因?yàn)橐粋€(gè)模塊被夾在到一個(gè)子域,它自己的淚定義不會(huì)在主程序的域中。例如,第一個(gè)模塊通過加載PopUpManager類而成為在整個(gè)程序中PopUpManager類的擁有者,因?yàn)樵撃K使用SingletonManager注冊了管理器。如果其他模塊在之后嘗試使用PopUpManager,AdobePlayer將拋出一個(gè)異常。
解決方案是確保例如PopUpManager和DragManager之類的管理器一級其他被共享的服務(wù)都被主程序定義(或者之后被記載到“殼”程序的域中)。當(dāng)你將這些類中的而一個(gè)提升到“殼”中,這個(gè)類就可以被所有的模塊使用。典型的,通過添加下面的腳本塊來實(shí)現(xiàn):
- importmx.managers.PopUpManager;
- importmx.managers.DragManager;
- privatevarpopUpManager:PopUpManager;
- privatevardragManager:DragManager;
這個(gè)技巧同樣殼被應(yīng)用于組件。模塊首先使用屬于其自身的且定義于其自身域中的組件。結(jié)果是,如果其他模塊嘗試使用一個(gè)已經(jīng)被另一的模塊所以用的組件,那么它的定義不會(huì)匹配已經(jīng)存在的定義。要避免組件定義被錯(cuò)誤的匹配,就要在主程序中創(chuàng)建一個(gè)組件的實(shí)力。這樣,那個(gè)組件的定義將被主程序應(yīng)用,并且可以被其他任何字域中的組件使用。
因?yàn)橐粋€(gè)Flex模塊在于加載它的程序相同的安全域中,當(dāng)你在一個(gè)AIR程序中使用模塊時(shí),任何的模塊SWF文件必須位于與主程序SWF文件相同的目錄或位于主程序SWF文件所在目錄的子目錄中,以確保主程序SWF和模塊SWF位于AIR程序的安全沙箱中。這一點(diǎn)可通過模塊的路徑不需要"../"記號來從程序目錄或程序的某個(gè)子目錄向外導(dǎo)航加以印證。
Flex模塊化程序
要?jiǎng)?chuàng)建一個(gè)Flex模塊化的程序,你要為每個(gè)模塊創(chuàng)建獨(dú)立的類,以及加載這些模塊的程序。
創(chuàng)建一個(gè)Flex模塊化程序
1.創(chuàng)建任意數(shù)量的模塊。一個(gè)基于MXML的模塊文件的根標(biāo)記是<mx:Module>?;贏ctionScript的模塊繼承自Module或ModuleBase類。
2.編譯每個(gè)模塊。你可以使用mxmlc命令行編譯器或AdobeFlexBuilder內(nèi)建的編譯器進(jìn)行編譯。
3.創(chuàng)建一個(gè)Aplication類,可以是一個(gè)典型的根元素為<mx:Applicaton>的MXML文件,也可以是一個(gè)只有ActionScript的程序。
4.在Application文件中,使用<mx:ModuleLoader>標(biāo)簽來加載每個(gè)模塊。你也可以使用mx.modules.ModuleLoader和mx.modules.ModuleManager類的方法來加載模塊。
編寫模塊
模塊是就像程序文件一樣的淚。你可以在ActionScript中創(chuàng)建它們,也可以通過使用MXML標(biāo)簽擴(kuò)展Flex類的方法創(chuàng)建它們,即:你可以在MXML或ActionScript中創(chuàng)建模塊。
創(chuàng)建基于MXML的模塊
要在一個(gè)MXML種創(chuàng)建模塊,你需要通過創(chuàng)建一個(gè)根元素為<mx:Module>的MXML文件來mx.modules.Module類。在那個(gè)標(biāo)簽中,可以添加任意的命名空間。你必須在文件頭包含XML類型生命標(biāo)簽,如下所示:
- <?xmlversionxmlversion="1.0">
- <mx:Modulexmlns:mxmx:Modulexmlns:mx="http://www.adobe.com/2006/mxml"width="100%"height="100%">
- <mx:Script>
- <![CDATA[
- importmx.collections.ArrayCollection;
- [Bindable]
- publicvarexpenses:ArrayCollection=newArrayCollection([
- {Month:"Jan",Profit:2000,Expenses:1500},
- {Month:"Feb",Profit:1000,Expenses:200},
- {Month:"Mar",Profit:1500,Expenses:500}
- ]);
- ]]>
- </mx:Script>
- <mx:ColumnChartidmx:ColumnChartid="myChart"dataProvider="{expenses}">
- <mx:horizontalAxis>
- <mx:CategoryAxis
- dataProvider="{expenses}"
- categoryField="Month"
- />
- </mx:horizontalAxis>
- <mx:series>
- <mx:ColumnSeries
- xField="Month"
- yField="Profit"
- displayName="Profit"
- />
- <mx:ColumnSeries
- xField="Month"
- yField="Expenses"
- displayName="Expenses"
- />
- </mx:series>
- </mx:ColumnChart>
- <mx:LegenddataProvidermx:LegenddataProvider="{myChart}"/>
- </mx:Module>
在你編譯一個(gè)模塊后,你可以在一個(gè)程序或另一個(gè)模塊中加載它。你可以用下面介紹的技巧來加載基于MXML的模塊:
ModuleLoaderModuleLoader類提供了高層的處理模塊的API。
ModuleManagerModuleManager類提供了較ModuleLoader更底層的處理模塊的API。
創(chuàng)建基于ActionScript的模塊
要在ActionScript中創(chuàng)建一個(gè)模塊,你可以創(chuàng)建一個(gè)繼承自mx.modules.Moddule類或mx.moduls.ModuleBase類的文件。
擴(kuò)展Module類與在MXML文件中使用<mx:Module>標(biāo)記的效果相同。如果你的模塊與框架交互,就應(yīng)該擴(kuò)展這個(gè)類。這意味著將向顯示列表添加對象,或與顯示對象發(fā)生交互。
要查看一個(gè)擴(kuò)展Module類的ActionScript類的例子,可以先創(chuàng)建一個(gè)根元素為<mx:Module>的MXML文件。當(dāng)你編譯這個(gè)文件的時(shí)候,將keep-generated-actionscript編譯選項(xiàng)設(shè)定為true。Flex的編譯器將在一個(gè)叫做generated的目錄中保存生成的類。你將注意到生成的類中包含著一些你可能尚不了解的代碼,其結(jié)果是你可能無法編寫擴(kuò)展Module類的基于ActionScript的模塊,而是使用MXML文件的方式來代替。
如果你的模塊不包含任何框架代碼,你可以創(chuàng)建一個(gè)繼承自ModuleBase的淚。如果你使用ModuleBse類,你的模塊將比使用基于Module類的時(shí)候更小,因?yàn)樗话魏我蕾嚨目蚣艽a。
下面的例子創(chuàng)建了一個(gè)簡單的、不包含任何框架代碼的,且繼承自ModuleBase類的模塊:
- package{
- importmx.modules.ModuleBase;
- publicclassSimpleModuleextendsModuleBase{
- publicfunctionSimpleModule(){
- trace("SimpleModulecreated");
- }
- publicfunctioncomputeAnswer(a:Number,b:Number):Number{
- returna+b;
- }
- }
- }
【編輯推薦】
- Flex模塊化應(yīng)用程序開發(fā)
- Flex模塊化的目的和方法
- 技術(shù)前沿 看Flex客戶端緩存技術(shù)如何使用
- 解析Flex全屏模式設(shè)置方法
- Flex內(nèi)存泄露解決方法和內(nèi)存釋放優(yōu)化原則