Modular

          簡(jiǎn)單的說(shuō),Modular(模塊)和Shell(殼)就象DLL(動(dòng)態(tài)鏈接庫(kù))和EXE(可執(zhí)行程序)之間的關(guān)系一樣.例如我們?cè)趯?xiě)WINDOWS的應(yīng)用程序的時(shí)候可以調(diào)用大量的MICROSOFT提供的DLL里的方法(我們稱之為API).同樣的,我們也可以自己把功能相同或者同類(lèi)的方法抽象成為動(dòng)態(tài)鏈接庫(kù)以方便我們的后續(xù)開(kāi)發(fā),升級(jí),團(tuán)隊(duì)開(kāi)發(fā)等等. 因此顯然,Modular的推出更有利于我們開(kāi)發(fā)程序的模塊化.可能有人會(huì)說(shuō),這樣的功能我們同樣可以采用編譯多個(gè)可執(zhí)行SWF,然后用Loader載入不就行了?的確我不反對(duì)這樣的做法,事實(shí)證明,這也可以被正確實(shí)施于未更新的版本的.不一樣的是.

          1.例如我們?cè)谀K中包含Application的標(biāo)簽,大家可以去看一下它的依賴關(guān)系就知道為什么只寫(xiě)一個(gè)Helloworld就會(huì)生成>100K的原因了.而事實(shí),這些東西我們?cè)谥鞒绦蛑衅鋵?shí)是包含了這些類(lèi)的.類(lèi)的重復(fù)被編譯導(dǎo)致文件變得更大.

          2.Application標(biāo)簽是可以被運(yùn)行的,簡(jiǎn)單的說(shuō),Application編譯的SWF可以直接運(yùn)行,這樣我們的編程似乎就成了EXE和EXE的嵌套,似乎有點(diǎn)奇怪? 而Modular本身是不可執(zhí)行的,就象DLL一樣,里面可以包含很多方法也可以包含許多窗體,但事實(shí)自身是不可被運(yùn)行的.而這些好處在Modular里可以輕松的實(shí)現(xiàn).

           

          好的,現(xiàn)在我們來(lái)直接一點(diǎn)吧,看一下例子.

           

          代碼下載: http://res.ezse.com/Howto/ModularDemo.rar

           

          我們?cè)贔LEX BUILDER里建立三個(gè)項(xiàng)目,一個(gè)專門(mén)放MODULARS,一個(gè)為SHELL,最后一個(gè)是Interface.當(dāng)然,視需要我們也可以建立多個(gè)項(xiàng)目.

              當(dāng)然,Shell(ModularMain)就是我們的主程序,相當(dāng)于我們的EXE文件;

                  Modulars(Modulars)就是我們的DLL文件的聚集地J 當(dāng)然合適的建立模塊,可以使得我們的程序更具擴(kuò)展性和部署.

                  Interface(UserModularsInterface)這不是必須的,但我建議在團(tuán)隊(duì)合作和大型程序開(kāi)發(fā)的時(shí)候采用接口.接口的具體功能我就不在這里說(shuō)了,可以找本OOD書(shū)看一下.簡(jiǎn)單的說(shuō)就是模塊之間混合編程所統(tǒng)一的必須的方法或?qū)傩?接口沒(méi)有具體的實(shí)現(xiàn)方法,只是聲明了方法或?qū)傩?

              

              在這個(gè)例子中,我們建立了三個(gè)Modular,一個(gè)是在Shell項(xiàng)目中的InnerModular.mxml . 另一個(gè)是在Modulars中的OuterModular.mxml . 這個(gè)Modular和InnerModular相似. 最后一個(gè)是在Modulars中的OuterModularWithInterface.mxml . 這個(gè)Modular和前兩個(gè)區(qū)別不大,僅僅是使用了Interface(推薦使用這種方式).

           

              首先我們看一下Inner Modular. 為什么取名為Inner Modular是因?yàn)檫@個(gè)Modular是和Shell在同一個(gè)Project中.

           

          InnerModular.mxml

          <?xml version="1.0" encoding="utf-8"?>

          <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

          <mx:Script>

              <![CDATA[

                  [Bindable]

                  public var textValue:String = "(default inner text value)";

              ]]>

          </mx:Script>

              <mx:Label text="{textValue}"/>

          </mx:Module>

           

          在源程序中,唯一要注意的就是我們新建一個(gè)Application的時(shí)候,紅色標(biāo)記部分是引用的Application標(biāo)簽.把它改為Module即可.

           

          引用中,ModularMain.mxml

           

          <?xml version="1.0" encoding="utf-8"?>

          <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">

          <mx:Script>

              <![CDATA[

                  import mx.modules.*;

                  import mx.events.ModuleEvent;

                  

                  private var mdInnerModular:Object;

                  private function init():void

                  {

                      mdInner.addEventListener(ModuleEvent.READY,onInnerModularLoaded);

                  }

                  private function onInnerModularLoaded(evt:ModuleEvent):void

                  {

                      mdInnerModular = mdInner.child;

                      mdInnerModular.textValue = "Inner Modular";

                  }

                  private function CallIOuterModularFunction():void

                  {

                      var iOuter:IOuterModular = mdOuterWithInterface.child as IOuterModular;

                      iOuter.SetText("IOuter Called");

                  }

              ]]>

          </mx:Script>

              <mx:ModuleLoader id="mdInner" url="InnerModular.swf"/>

              <mx:ModuleLoader id="mdOuter" url="assets/OuterModular.swf" y="20"/>

              <mx:Button label="Set Outer Modular Value" click="(mdOuter.child as Object).textValue = 'Outer Modular'" y="40"/>

              <mx:Button label="Call Outer Modular Function" click="(mdOuter.child as Object).testFunction()" y="70"/>

              <mx:ModuleLoader id="mdOuterWithInterface" url="assets/OuterModularWithInterface.swf" y="90"/>

              <mx:Button label="Call Outer Modular Function" click="CallIOuterModularFunction()" y="120"/>

          </mx:Application>

           

          Shell中的有紅色部分是對(duì)InnerModular的操作.注意的就是要執(zhí)行Modular中的方法或者更改屬性必須等ModularLoader觸發(fā)了ModuleEvent.READY 后才能執(zhí)行.

           

          OuterModular.mxml:

          <?xml version="1.0" encoding="utf-8"?>

          <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

          <mx:Script>

              <![CDATA[

                  [Bindable]

                  public var textValue:String = "(default outer text value)";

                  public function testFunction():void

                  {

                      this.textValue = "Outer Function Called";

                  }

                  

              ]]>

          </mx:Script>

              <mx:Label text="{textValue}" />

          </mx:Module>

           

          內(nèi)容和InnerModular一樣.不一樣的是放在了另一個(gè)Project中.

           

          而我推薦的是使用Interface.下面我們就看一下使用了Interface的操作方法.

          1. 首先我們要定義Interface文件,為了方便,我們新建立一個(gè)Lib Project.這樣編譯后會(huì)生成一個(gè)swc的可被引用的代碼包.
          2. 在Shell和Modular的Project中添加引用.
          3. 在Modular中實(shí)現(xiàn)具體的接口中定義的方法或?qū)傩?

           

          IOuterModular.as

          package

          {

              import flash.events.IEventDispatcher;

              public interface IOuterModular extends IEventDispatcher

              {

                  function SetText(val:String):void;

              }

          }

           

          在接口中,我們定義了SetText這個(gè)方法.于是我們?cè)贛odular中先實(shí)現(xiàn)這方法:

          OuterModularWithInterface.mxml

          <?xml version="1.0" encoding="utf-8"?>

          <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" implements="IOuterModular">

          <mx:Script>

              <![CDATA[

                  [Bindable]

                  public var textValue:String = "(default outer(with interface) text value)";

                  

                  public function SetText(val:String):void

                  {

                      this.textValue = val;

                  }

              ]]>

          </mx:Script>

              <mx:Label text="{textValue}" />

          </mx:Module>

           

          其中紅色部分標(biāo)記了此Modular為接口IOuterModular的實(shí)現(xiàn). 藍(lán)色部分則是具體實(shí)現(xiàn)的方法.

           

          ModularMain.mxml的橙色部分則是它的使用方法.

           

          和不用接口不一樣的地方是: var iOuter:IOuterModular = mdOuterWithInterface.child as IOuterModular;新建一個(gè)實(shí)體,此實(shí)體正是ModularLoader的child.這里可能要注意一下,這個(gè)child可能是Flex的Bug,這個(gè)child是一個(gè)DisplayObject,例如我們這樣寫(xiě)mdOuterModular.child.SomeFunction().編譯無(wú)法通過(guò),提示是DisplayObject沒(méi)有這個(gè)方法(廢話).但是在調(diào)試模式下可以看到,這個(gè)child并非一個(gè)DisplayObject. 因此很郁悶,必須把這個(gè)child 設(shè)置成Object才能執(zhí)行里面的方法.

          用接口還有一個(gè)好處,那就是可以直接看到Modular中的方法和屬性.而在前兩個(gè)例子中是沒(méi)有這種功能的.

           

          另一個(gè)要注意的地方是,如果我們的Modular的Width,Height設(shè)置成的是100%, 而在ModularLoader中設(shè)置了Width和Height為絕對(duì)值的時(shí)候,會(huì)發(fā)現(xiàn),事實(shí)上,Modular并沒(méi)有填充這個(gè)固定區(qū)域! 做實(shí)驗(yàn)的話可以在Modular中設(shè)置一個(gè)Canvas.引用后會(huì)發(fā)現(xiàn)大小是0x0.所以我們可能在寫(xiě)這種高寬不定的時(shí)候,可能要建立一個(gè)方法,在Modular Ready后執(zhí)行方法來(lái)重設(shè)置它的大小.

           

              現(xiàn)在我們可以看到程序可以正常的被執(zhí)行了,但是Modular生成出來(lái)的swf個(gè)個(gè)都是100多K! 當(dāng)然,因?yàn)槲覀冞€沒(méi)有對(duì)Modulars Project進(jìn)行裁剪尺寸. 這個(gè)裁減過(guò)程的原理就是我們的主程序中已經(jīng)編譯了的類(lèi),在Modular中就不再編譯了.而如何設(shè)置呢?在Shell的Project中的編譯器的附加參數(shù)里設(shè)置為-locale en_US -link-report=d:/testreport.xml 這樣在編譯的時(shí)候會(huì)生成一個(gè)關(guān)于Shell里所引用過(guò)的類(lèi)庫(kù)列表在d:/testreport.xml的文件中. 在Modulars中的編譯器的附加參數(shù)里設(shè)置為-locale en_US -load-externs=d:/testreport.xml 這樣,在編譯Modulars的時(shí)候,載入Shell已經(jīng)編譯過(guò)的類(lèi)庫(kù).在編譯的時(shí)候就跳過(guò)這些類(lèi)庫(kù).再編譯一看,大小豁然小了100K,變成了10多k.

           

              在Dreamer的Blog上也有一篇翻譯的文章大家也可以去看一下: http://www.zhuoqun.net/article.asp?id=382

          posted on 2007-05-11 09:43 leoli 閱讀(715) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): Flex

          導(dǎo)航

          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          統(tǒng)計(jì)

          常用鏈接

          留言簿(6)

          隨筆分類(lèi)

          隨筆檔案(17)

          文章分類(lèi)(86)

          收藏夾(3)

          flex blog

          good site

          java blog

          my friend

          tools

          抓蝦

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 乌苏市| 哈尔滨市| 罗平县| 嘉义县| 博罗县| 通州区| 都兰县| 元江| 河池市| 巧家县| 洛川县| 巩留县| 阿荣旗| 手游| 鄱阳县| 临邑县| 弥渡县| 沙坪坝区| 岐山县| 治县。| 绍兴县| 交城县| 福泉市| 罗田县| 泽州县| 康定县| 洪洞县| 彝良县| 庆元县| 神木县| 平阳县| 萨嘎县| 铁岭县| 佛冈县| 阳高县| 乌拉特中旗| 拜城县| 双江| 大港区| 原平市| 拜泉县|