2007年9月19日

          一點(diǎn)感悟

          這兩天遇到的一些問題,引起的一些思考,覺得有必要寫下來(lái)。
          一. 面向?qū)ο蟮腁PI接口設(shè)計(jì),如何做到向后兼容。一個(gè)軟件存在多個(gè)模塊,如果提供基礎(chǔ)API的模塊變化了,那么依賴于它的應(yīng)用模塊都必須重新編譯和部署。這就對(duì)基礎(chǔ)API模塊的向后兼容性提出了要求。完全通用的方法是不存在的,任何方法都需要根據(jù)實(shí)際情況調(diào)整,這里僅僅提供一些比較通用但是也不明確的方法:
          方法一:擴(kuò)展時(shí)對(duì)象只增加方法和屬性,原有的屬性和方法保留。這對(duì)于c++等基于二進(jìn)制對(duì)象布局的方法在使用時(shí)需要非常小心,否則極易引起內(nèi)存訪問違規(guī)。但是對(duì)于ActionScript基于元數(shù)據(jù)的語(yǔ)言來(lái)說(shuō),這一方法一般不會(huì)有什么問題。對(duì)于Java的情況不是非常清楚,估計(jì)與actionscript情況差不多。
          方法二:增加新的對(duì)象(使用繼承)提供擴(kuò)展功能,原來(lái)的對(duì)象保留。不過對(duì)于耦合的類關(guān)系,只增加一個(gè)類往往并不能達(dá)到目的。

          這里必須注意的一點(diǎn)是,API提供者與API使用者保持單向依賴的關(guān)系,API不應(yīng)該依賴于具體的應(yīng)用。對(duì)于多模塊的軟件來(lái)說(shuō)架構(gòu)最重要的是兩點(diǎn):
          1. 從需求中抽象出API,并且將API的開發(fā)交給素質(zhì)較高的人員,而應(yīng)用之間松散耦合,通過API發(fā)生關(guān)系。
          2. API本身空間也要做劃分,將之切割成為正交的空間,這樣API擴(kuò)展時(shí),影響控制在局部。


          順便說(shuō)說(shuō)向前兼容的問題,這要求新的Client兼容老的API,這在API設(shè)計(jì)中很少碰到,但是在設(shè)計(jì)軟件的文檔存儲(chǔ)格式(Save/Load)時(shí)常常遇到,這要求新的應(yīng)用在開發(fā)時(shí),做判斷,判斷屬性不存在時(shí)應(yīng)該如何處理,也就是提供一個(gè)默認(rèn)值。

          對(duì)于其它的Server-Client結(jié)構(gòu),比如WebService的擴(kuò)展,XML擴(kuò)展等等,我想也應(yīng)該有類似的方法。所以我也想去看看一些公開的API接口是如何設(shè)計(jì)和擴(kuò)展的,比如FaceBook,不過說(shuō)到底還是抽象與空間劃分的問題,而這些并沒有通用的方法,都依賴于具體的需求。

          二. 面向接口的設(shè)計(jì)實(shí)際上就是合理的劃分對(duì)象空間。對(duì)于對(duì)象在擴(kuò)展時(shí),我們常常會(huì)發(fā)現(xiàn)并沒有辦法把它劃分成樹狀的類關(guān)系,常常我們發(fā)現(xiàn)從一個(gè)類A派生了兩個(gè)類B和C,但是又存在第三種情況,它的行為包含部分B的行為也包含部分C的行為。實(shí)際上類的空間劃分,和數(shù)據(jù)庫(kù)設(shè)計(jì)是一樣的,每一次劃分(繼承)相當(dāng)于以一個(gè)索引劃分對(duì)象空間,但是很多時(shí)候劃分有多個(gè)索引,這時(shí)候要想劃分成單一的一棵樹是不可能的。這時(shí)候就需要進(jìn)一步細(xì)化對(duì)象的空間劃分,并將之劃分為正交的多個(gè)空間。舉個(gè)例子:Window派生出TransparentWindow和OpaqueWindow,這是一種劃分,但是我們又發(fā)現(xiàn)另一種劃分,WindowWithTitleBar與WindowWithoutTitleBar,他們都是對(duì)Window的劃分。這時(shí)候我們應(yīng)該想到的是,Window可以拆分為:ITitleBar, IMainWindow,各種Window可以選擇實(shí)現(xiàn)或者不實(shí)現(xiàn)這些接口。當(dāng)?shù)谌呤褂眠@些對(duì)象時(shí),直接訪問接口即可,因?yàn)槠渌慕涌诳赡苁撬麄儾⒉魂P(guān)心的。當(dāng)存在多種索引時(shí),將對(duì)象拆分為正交的空間,每一個(gè)空間尤其自己的單一索引,這應(yīng)該是對(duì)象劃分的一種通用原則。就像單根繼承一樣,這樣會(huì)使得對(duì)象的劃分結(jié)構(gòu)非常清晰。
          對(duì)于某些不是特別復(fù)雜的情況,如果存在多種劃分索引,不妨用單一的類表示全部的對(duì)象,對(duì)某些對(duì)象,某些屬性方法是無(wú)效的,這樣實(shí)際上在簡(jiǎn)單情況下是很有效的,因?yàn)檫^度的劃分會(huì)造成復(fù)雜性,使用者可能不知道在哪個(gè)對(duì)象上找到他需要的屬性或方法了,這就好像在一張表上設(shè)計(jì)了全部的屬性,盡管有些屬性是抵觸的,有些屬性是相關(guān)的。隨著不斷的擴(kuò)展,這張表會(huì)越來(lái)越大,這就需要開始對(duì)對(duì)象空間做劃分了,所以說(shuō)到底,還是一個(gè)需求復(fù)雜度的問題,這里最重要的是掌握一個(gè)劃分的度,何時(shí)劃分,劃分到什么程度,決定這些的往往不僅僅是技術(shù)因素,還有商業(yè)上,運(yùn)營(yíng)上,時(shí)間上,成本上的因素,這也是最難判斷的一點(diǎn),需要在實(shí)際中去具體問題具體分析,這里就能體現(xiàn)經(jīng)驗(yàn)的重要性了,其實(shí)在架構(gòu)上方法都是很Genralized的,這些和實(shí)現(xiàn)一個(gè)具體的算法大部相同,所以設(shè)計(jì)模式都在講模式一定有其上下文,也是這個(gè)道理嗎

          胡扯了很多,先到這里吧,等有時(shí)間做進(jìn)一步的整理

          posted @ 2008-08-15 17:40 雁過無(wú)痕 閱讀(330) | 評(píng)論 (0)編輯 收藏

          國(guó)內(nèi)的Flex資源

          AnyFlex
          RIAchina
          RXNA類似國(guó)外的mxna)
          Flex搜索引擎計(jì)劃:http://blog.eshangrao.com/index.php/2007/02/27/352-googleflex
          Flex Wiki計(jì)劃:http://blog.eshangrao.com/index.php/2007/05/12/390-flexwikiflex
          RIAmeeting:http://www.riameeting.cn/

          Flex對(duì)于信息發(fā)布類網(wǎng)站不一定有效,但交互性要求很高的社區(qū)類網(wǎng)站就很合適

          posted @ 2008-02-28 16:12 雁過無(wú)痕 閱讀(378) | 評(píng)論 (0)編輯 收藏

          竹林深處寬屏壁紙

          http://www.aar.cn/wallpaper/Desktop/Natural/2150/F_WQTP_1680x1050_Q.Html

          posted @ 2008-02-27 18:45 雁過無(wú)痕 閱讀(365) | 評(píng)論 (0)編輯 收藏

          Flex SDK Open Source Site Online

          http://opensource.adobe.com/wiki/display/site/Source

          posted @ 2008-02-26 11:38 雁過無(wú)痕 閱讀(307) | 評(píng)論 (0)編輯 收藏

          Dont't treat software as an artifact, but as a process of engagement with your users

          Fellow evangelist Duane Nickull has posted the slides from his Web 2.0 Design Patterns, Models and Analysis presentation

          posted @ 2008-01-17 11:33 雁過無(wú)痕 閱讀(268) | 評(píng)論 (0)編輯 收藏

          Inversion of Control for Actionscript 3.0

          http://www.pranaframework.org/

          reference:
          Inversion of Control Containers and the Dependency Injection Pattern, by Martin Fowler


          Prana是一個(gè)用Actionscript寫的IoC Framework,理念和Spring非常類似,目的是為了盡可能降低類之間的依賴性,通過xml配置文件使得編譯依賴性降低,可以動(dòng)態(tài)裝配。這在Java的世界里是非常有意義的,因?yàn)樗械氖虑槎及l(fā)生在server端,Client端并不需要知道這一切。但是在Flex的世界里,swf是客戶端下載下來(lái)運(yùn)行在client,如果要達(dá)到動(dòng)態(tài)裝配的目的,client必須能夠有最新需要?jiǎng)討B(tài)裝配的class的字節(jié)碼,這必然要求swf重新編譯,那么這就失去了Ioc的意義了

          posted @ 2008-01-09 17:42 雁過無(wú)痕 閱讀(365) | 評(píng)論 (0)編輯 收藏

          Module之間的通信交互解決辦法

          看看以下的代碼,有點(diǎn)意思
          1.子Swf的Code,SampleChildren.mxml

          <?xml version="1.0" encoding="utf-8"?>
          <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
              
          <mx:Script>
                  
          <![CDATA[
                      import mx.managers.SystemManager;
                      public 
          function output(s:String):void{
                          trace(s);
                      }

                      
                      public 
          function CallFriend():void{
                          SampleChildren(_SystemManager.application).output(
          "call");
                      }

                      
                      private 
          var _SystemManager:SystemManager;
                      
                      public 
          function register(ASystemManager:SystemManager):void{
                          _SystemManager
          =ASystemManager;
                      }

                          
                  ]]
          >
              
          </mx:Script>
          </mx:Application>

          2.主swf的Code, SampleParent.mxml
          <?xml version="1.0" encoding="utf-8"?>
          <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
              
          <mx:Script>
                  
          <![CDATA[
                      import mx.managers.SystemManager;
                      
                      
          var Children1,Children2:SystemManager;
                      
                      private 
          function onClick(e:Event):void{
                          SampleChildren(Children1.application).register(Children2);
                          SampleChildren(Children2.application).register(Children1);
                      }

                      
                      private 
          function initNestedAppProps():void {
                          Children1 
          = SystemManager(myLoader.content);
                          trace(Children1.application);
                      }

                      private 
          function initNestedAppProps2():void {
                          Children2 
          = SystemManager(myLoader2.content);
                          trace(Children2.application);
                      }

                      
                      private 
          function onC1(e:Event):void{
                          SampleChildren(Children1.application).CallFriend();
                      }
            
                      private 
          function onC2(e:Event):void{
                          SampleChildren(Children2.application).CallFriend();
                      }
                        
                      
                  ]]
          >
              
          </mx:Script>
              
          <mx:Button label="ClickMe" click="onClick(event);"/>
              
              
          <mx:Button label="c1 call c2" click="onC1(event);"/>
              
          <mx:Button label="c2 call c1" click="onC2(event);"/>
              
              
          <mx:SWFLoader id="myLoader" width="300"
                  source
          ="SampleChildren.swf"
                  creationComplete
          ="initNestedAppProps();"/>
              
          <mx:SWFLoader id="myLoader2" width="300"
                  source
          ="SampleChildren.swf"
                  creationComplete
          ="initNestedAppProps2();"/>    
          </mx:Application>

          注意到SampleParent.mxml文件中SampleChildren類的使用了么,原來(lái)mxml文件也是對(duì)應(yīng)一個(gè)同名的actionscript class的,這個(gè)class是從Application派生的。但是要注意哦,SampleParent.mxml編譯時(shí)必須能夠看到SampleChildren類的Source。

          posted @ 2008-01-04 12:27 雁過無(wú)痕 閱讀(505) | 評(píng)論 (0)編輯 收藏

          轉(zhuǎn)貼兩篇關(guān)于Flex FrameWork以及模塊化開發(fā)的文章,第一篇Flex Framework Fundamentals

          轉(zhuǎn)載自:http://www.cnblogs.com/sharplife/archive/2007/09/03/880641.html

          最近看時(shí)學(xué)習(xí)Flex應(yīng)用,開始對(duì)Flex和Flash的關(guān)系有些模糊,讀了Oreilly的Programming Flex 2才算是明白些,現(xiàn)記下。

          1、Flex應(yīng)用程序的生命周期
          Flex應(yīng)用就其根本上講就是Flash應(yīng)用,只不過其是基于Flex Framework(由ActionScript寫就)開發(fā)的。Flex應(yīng)用程序的根對(duì)象的是SystemManager(不是我們?cè)趂lex應(yīng)用上看到的Application根元素),繼承自flash.dispaly.MovieClip—flash player display type,MovieClip是一種支持timeline基本元素幀frame的對(duì)象,在Flex Framework中SystemManager是特殊的,含有兩幀(其他component都是一幀的),分別是preloader和真正的Application,preloader幀可以迅速下載下來(lái)并用于顯示應(yīng)用下載進(jìn)度,一旦Flex應(yīng)用的SystemManager實(shí)例進(jìn)入第二幀,將創(chuàng)建Flex主應(yīng)用application實(shí)例并賦予本身的屬性application(在進(jìn)入第二幀之前是null),自此application(flex主應(yīng)用)的內(nèi)部生命周期、事件開始運(yùn)作:
          preinitialize:application已經(jīng)實(shí)例化但尚未創(chuàng)建任何child component
          initialize:已經(jīng)創(chuàng)建child component但對(duì)其進(jìn)行布局(lay out)
          creationComplete:application已經(jīng)完成實(shí)例化并完成所有child component的布局
          SystemManager有一個(gè)topLevelSystemManager對(duì)象,指向一個(gè)SystemManager實(shí)例,是所有當(dāng)前在flash player運(yùn)行的任何東西的根(root),如果flex被作為主應(yīng)用加載到flash player則上述屬性將指向其本身(self-refrencing),但當(dāng)flex應(yīng)用是被另一flex應(yīng)用載入的,其自身的SystmenManager的topLevelSystemManager屬性則不是自引用了,而是指向其父應(yīng)用的SystemManager實(shí)例。所有UIComponent的子類都有一個(gè)systemManager屬性指向應(yīng)用的SystemManager實(shí)例,在被SystemManger實(shí)例監(jiān)聽的component的事件發(fā)生冒泡時(shí),其將擁有事件處理鏈上最后的處理權(quán)。

          2、Flash palyer和Framwork的區(qū)別
          Flash player是Flex應(yīng)用和flash應(yīng)用的運(yùn)行環(huán)境,兩應(yīng)用對(duì)其擁有完全平等的操作權(quán)(通過Flash player提供的API),兩應(yīng)用形成的.swf文件在flash player中是同樣的表現(xiàn),不同的不是應(yīng)用的內(nèi)容而是其各自的創(chuàng)建方式。Flex的Framework在開發(fā)和運(yùn)行之間為應(yīng)用提供了一層抽象,F(xiàn)lex應(yīng)用編譯時(shí)會(huì)將必要的framwork library編譯進(jìn).swf文件(同樣影響應(yīng)用文件的大小等),主要的flash player class當(dāng)然不會(huì)被編譯到.swf中,因?yàn)樗麄円呀?jīng)存在于flash player中了,最終形成與flash應(yīng)用同樣的flash player可以理解的指令。
          關(guān)于flash player class和flex framework的區(qū)分很方便,前者的class以flash開頭,如flash.net.URLLoader,而后者則以mx開頭,如mx.controls.Button

          3、動(dòng)態(tài)載入另外的flex應(yīng)用
          <mx:SWFLoader source=”src/*.swf”/>
          Swfloader的content屬性指向被載入的flex應(yīng)用的SystemManager實(shí)例(其application屬性指向被載入felx應(yīng)用的Application實(shí)例),swfloader加載、初始化被載入flex應(yīng)用時(shí)會(huì)dispatch出init事件,可與其中監(jiān)聽被載入flex應(yīng)用的SystemManager實(shí)例的ApplicationComplete事件,事件發(fā)生時(shí)被載入content的Application對(duì)象方可以引用
          與inithandler中event.target.content.addEventListener(FlexEvent.APPLICATION_COMPLETE,func);
          與applicationCompleteHandler中event.target.application.method…

          4、理解應(yīng)用程序域(application domain)
          一個(gè)應(yīng)用程序domain(類似于.net的appdoamin)中有flex應(yīng)用的相關(guān)類定義、資源等,被載入的新flex應(yīng)用可以存在于一個(gè)全新的、隔離的domain中(占額外的內(nèi)存資源)、可以存在于當(dāng)前domain的子doamin中(共享父domain的資源、類定義,須注意類定義被取代的情況)、也可以直接存在與當(dāng)前doamin中(同樣須注意類定義沖突),如runtime shared library。
          代碼中實(shí)現(xiàn)這三種方式的應(yīng)用(主要應(yīng)用到flash.system.LoaderContext、flash.display.Loader或flash.net.URLLoader、flash.system.ApplicationDomain)

          var context:LoaderContext = new LoaderContext( );
          context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);//載入作為子domain
          context.applicationDomain = new ApplicationDomain();//載入作為全新domain
          context.applicationDomain = ApplicationDomain.currentDomain;//載入當(dāng)前domain
          var request:URLRequest = new URLRequest("RuntimeLoadingExample.swf");
          var loader:Loader = new Loader( );
          loader.load(request, context);

          5、關(guān)于preloader
          Preloader是一個(gè)輕量級(jí)的類,在systemManager的第一幀被實(shí)例化,preloader會(huì)dispatch出一系列的事件,由progress bar監(jiān)聽實(shí)現(xiàn)loading界面,一旦應(yīng)用進(jìn)入第二幀待application初始化后會(huì)借由system manager通知preloader初始化進(jìn)度,preloader通知system manager其準(zhǔn)備待刪除
          Preloader的事件dispatch:
          progress
          Indicates download progress
          complete
          Indicates that the download is complete
          rslError
          Indicates that a runtime shared library could not load
          rslProgress
          Indicates the download progress for a runtime shared library
          rslComplete
          Indicates that the download is complete for runtime shared libraries
          initProgress
          Indicates that the application is initializing
          initComplete
          Indicates that the application has initialized

          如此,preloader可以定制化了。

          Over,暈倒!~

          posted @ 2008-01-04 12:19 雁過無(wú)痕 閱讀(1838) | 評(píng)論 (1)編輯 收藏

          VC中IDE中調(diào)試與運(yùn)行時(shí)行為不一致的原因

          有時(shí)會(huì)出現(xiàn)IDE中調(diào)試時(shí)出錯(cuò),但是在外部直接運(yùn)行程序不出錯(cuò)的情況,或者反之,出現(xiàn)這種情況的原因一般都是“當(dāng)前路徑”引起的,也就是CurrentPath不一樣,這可能導(dǎo)致dll加載搜索路徑不一樣,以及其它一些路徑引起的問題。

          posted @ 2007-11-28 20:57 雁過無(wú)痕 閱讀(604) | 評(píng)論 (1)編輯 收藏

          Flex 中的Event Propogation

          Flex中的Event傳遞主要有三個(gè)階段:capturing, targeting, bubbling。比如一個(gè)Button收到了一個(gè)消息,首先會(huì)從其根父UI Object上開始逐步Capture直到其父Object,然后由該Button履行Target階段,最后再以Capture相反的方向Bubble。當(dāng)然這些階段都是相對(duì)DisplayObject來(lái)說(shuō)的,對(duì)于其他的Object比如Socket,Event只會(huì)交給Target對(duì)象處理。

          先來(lái)看Capture階段:

          這個(gè)階段是從父到子的一個(gè)過程,典型應(yīng)用:myPanel.addEventListener(MouseEvent.MOUSE_DOWN, clickHandler, true);

          注意第三個(gè)參數(shù)useCapture被設(shè)為true,表示clickHandler只想處理Capture過程的事件,如果還想處理bubble階段的事件,那么必須再以u(píng)seCapture=false調(diào)用一次addEventListener

          Flex Develop Guide中有一句話:The capturing phase is very rarely used, and it can also be computationally intensive. By contrast, bubbling is much more common.我還不是特別理解,先寫下來(lái)再說(shuō)吧。

          再看Target階段:

          這個(gè)很簡(jiǎn)單,由DispatchEvent的對(duì)象直接處理。

          然后是Bubble階段。Bubble階段只有bubbles屬性為true的Event才會(huì)有這個(gè)過程,包括change, click, doubleClick, keyDown, keyUp, mouseDown, and mouseUp等事件。對(duì)于自定義事件,bubbles能否設(shè)成true還未知,因?yàn)樗坪跏侵蛔x的,還有待驗(yàn)證。

          posted @ 2007-09-19 22:51 雁過無(wú)痕 閱讀(687) | 評(píng)論 (0)編輯 收藏

          <2007年9月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(7)

          隨筆檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 钟祥市| 高尔夫| 韩城市| 德清县| 本溪市| 舒兰市| 青河县| 平舆县| 柯坪县| 嘉定区| 武穴市| 康定县| 奎屯市| 宝清县| 建湖县| 永泰县| 沐川县| 金沙县| 江永县| 衡山县| 教育| 泽库县| 瑞丽市| 九寨沟县| 大邑县| 五峰| 泸水县| 孝感市| 文水县| 隆子县| 龙游县| 治多县| 阿城市| 平顺县| 兖州市| 峨眉山市| 东至县| 池州市| 忻城县| 贡觉县| 客服|