emu in blogjava

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            171 隨筆 :: 103 文章 :: 1052 評論 :: 2 Trackbacks

          關(guān)于面向構(gòu)件的一些思考

          author:emu(黃希彤)  

          一、xml和元數(shù)據(jù)解決了接口脆弱性問題嗎?

           

          其實面向構(gòu)件的基本理念和傳統(tǒng)的模塊、對象并沒有大的區(qū)別,我們的目標(biāo)仍然是把“大問題”分解成“小問題”來解決。那我們?yōu)槭裁葱枰嫦驑?gòu)件呢?關(guān)鍵是我們要重用對“小問題”的解決,來解決新的“大問題”。

           

              傳統(tǒng)的問題分解手段為什么在重用上有問題呢?關(guān)鍵在于黃柳青博士說說的“接口脆弱性”問題:在新的上下文之下,同一個“小問題”的解決往往略有一點(diǎn)差異。就是這點(diǎn)差異,我們沒有辦法直接重用原來的模塊,必需“略微”改變一下接口,添加一個新的參數(shù),這樣這個模塊往往就和原來的模塊無法兼容了(如果想保持兼容,就要修改對原來的模塊的引用,這又帶來了新的問題)。下次我們再想重用的時候,也許又需要添點(diǎn)不同的玩意兒了,如果上次添的玩意兒還有用,就在上次的的基礎(chǔ)上改,不然就在舊的模塊上面改……

           

              那么,標(biāo)簽數(shù)據(jù)和xml真的能解決我們遇到的問題嗎?我們假設(shè)一個場景來看看:

           

                 首先,我做一個模塊來計算個人所得稅,接口很簡單,接受一個金額,按照預(yù)定的公式計算出所得稅額,輸出計算出來的金額。在第一個產(chǎn)品里面這個模塊工作的很好。

              接著,有一個新的產(chǎn)品也需要計算個人所得稅,那么理所當(dāng)然我們會重用這個模塊,不過這次的需求有點(diǎn)不同,我的新客戶的雇員里面有外籍雇員,對外籍雇員我們的計算方式有點(diǎn)不同。那么現(xiàn)在接口需要添加一個國籍字段。

              又來一個單子。我們這個新客戶也有外籍雇員,而且這些外籍雇員還有不同的簽證類型,臨時工作簽證和長期工作簽證的稅率又有不同,這次我們需要添加一個簽證類型字段……

           

              如果我們用傳統(tǒng)的接口,那么我們一開始會這樣寫接口:

                        currency incomeTax(currency salary)

                 第二次則是

                        currency incomeTax(currency salary, Nationality nationality)

                 第二次則是

                        currency incomeTax(currency salary, Nationality nationality, VisaType visaType)

                 很顯然,我們在重用的時候會遇到麻煩。

           

                 換種方式寫接口,也許會有幫助

                 第一次:

                        currency incomeTax(Parameter parameter)

                 第二次:

                        currency incomeTax(Parameter parameter)

                 第三次:

                        currency incomeTax(Parameter parameter)

           

                 通過Parameter的多態(tài),我們可以保持住接口。在函數(shù)里面我們可以判斷Parameter的類型來決定怎么計算。這樣做有兩個主要問題,一是我們需要多維護(hù)一組Parameter類,二是有人說如果我們試圖在計算的時候先判斷參數(shù)類型的話,先賞自己兩耳光。

           

           

           

                 Ok,看來我們還需要更寬松的接口,那么還可以這樣

                 第一次:

                        currency incomeTax(Map parameter)

                 第二次:

                        currency incomeTax(Map parameter)

                 第三次:

                        currency incomeTax(Map parameter)

                

           

                 最后如果用xml,我們會得到:

                 第一次:

                        currency incomeTax(String parameterXML)

                 第二次:

                        currency incomeTax(String parameterXML)

                 第三次:

                        currency incomeTax(String parameterXML)

                 我們可以看到,這個接口和Map接口實質(zhì)上沒有區(qū)別,一個可以做到的原則上另一個也可以,但是使用上有兩點(diǎn)區(qū)別:一是Map容器里面我們可以放任意的對象,而用xml的話我們要用String來表示一切,因此還要在調(diào)用過程中進(jìn)行編碼、解碼(想像一下拿一部電影做base64編碼吧);二是即使傳遞的都是簡單的串,Map容器里面的數(shù)據(jù)可以快速的引用,而xml的數(shù)據(jù)我們要分析xml來獲取(更不要說java在解析xml方面確實不占優(yōu)勢,剛聽說java在一個測試中敗給.net就是被xml性能低下所拖累)。

           

              我們再看看接口脆弱性是不是真的被解決了。不錯,在一致的接口之下,我們幾乎始終都可以進(jìn)行有效的調(diào)用,在處理接口參數(shù)的時候自適應(yīng)各種數(shù)據(jù),用默認(rèn)值代替缺少的參數(shù)。但是這樣做的代價就是我們失去了編譯期參數(shù)檢查的好處,并且在接口發(fā)生變化的時候沒有辦法(至少我想不出辦法)提醒接口的潛在使用者。還是用前面的例子。在我們添加“國籍”這個參數(shù)的時候,用傳統(tǒng)的方式,函數(shù)的調(diào)用者會知道,但是不管是用map還是用xml,我們只能在沒有接收到nationality參數(shù)的時候使用默認(rèn)值Chinese,但是可以想像很多開發(fā)人員并不知道計算所得稅的時候還要知道國籍。我們怎么防止模塊的使用者在傳遞一個外國雇員的數(shù)據(jù)時忘了傳遞國籍呢?我能想得出的最好的辦法也只是把這個問題列入潛在問題清單里面,在code review的時候人工檢查。

           

                 嚴(yán)格的接口定義,可以讓機(jī)器幫助我們維持我們的正確性,但是犧牲的是靈活性和可重用性。寬松的接口在帶來靈活性和可重用性的同時,付出的代價是犯錯誤的可能性和排錯的困難性。

           

                 使用xml的額外的好處是,我們可以很容易的在不同的平臺和語言之間交互,但是至少在現(xiàn)在,我看不到這個優(yōu)勢能有任何體現(xiàn):EOS好像完全是java開發(fā)的。

           

              因此,我看不出xml+元數(shù)據(jù)在解決接口脆弱性上的銀彈般的神奇共用,在我看來,它甚至不如相對比較傳統(tǒng)的Map接口。

           

              很遺憾的是,關(guān)于EOS的“總線”概念我現(xiàn)在沒有辦法搜集的足夠的資料,我很不理解xml數(shù)據(jù)是在什么樣的一條“總線”上流動的,而Map形式的數(shù)據(jù)包在這樣一條“總線”上是否能夠發(fā)揮相同的作用author:emu(黃希彤)

           

          posted on 2005-06-21 08:54 emu 閱讀(2095) 評論(7)  編輯  收藏

          評論

          # re: 關(guān)于面向構(gòu)件和EOS的一些思考-xml和元數(shù)據(jù)解決了接口脆弱性問題嗎? 2005-06-21 10:08 大胃
          EOS的全稱是什么啊?也許是我的Canon單反在作祟,怎么看怎么像相機(jī)型號。呵呵  回復(fù)  更多評論
            

          # re: 關(guān)于面向構(gòu)件和EOS的一些思考-xml和元數(shù)據(jù)解決了接口脆弱性問題嗎? 2005-06-21 12:20 emu
          我不但不知道普元EOS是什么的縮寫,也不知道佳能EOS是什么的縮寫。
          你小子居然公然支持日貨哦,小心相機(jī)落到俺手里,拆無赦!  回復(fù)  更多評論
            

          # re: 關(guān)于面向構(gòu)件和EOS的一些思考-xml和元數(shù)據(jù)解決了接口脆弱性問題嗎? 2005-06-22 16:46 kasaluo
          EOS是Enterprise Operation System的縮寫  回復(fù)  更多評論
            

          # 知道了還不如不知道 2005-06-22 17:25 emu
          Enterprise Operation System?企業(yè)操作系統(tǒng)?
          聽起來好像是windows 2003 enterprise之類的東東哦,一點(diǎn)都體現(xiàn)不出它真實的意義和價值,還是叫縮寫算了。  回復(fù)  更多評論
            

          # re: 關(guān)于面向構(gòu)件和EOS的一些思考-xml和元數(shù)據(jù)解決了接口脆弱性問題嗎? 2005-06-29 16:01 daxia
          我們一下程序采用map傳遞,這樣好處是,借口穩(wěn)定
          可以采用一個xml來描述map中的內(nèi)容,這樣在運(yùn)行時刻可以校驗
          但這樣導(dǎo)致很多 硬編碼的map 的key,并且可讀性也不好

          基本相當(dāng)于一個全局函數(shù),用了一些,后來盡量不使用了。  回復(fù)  更多評論
            

          # re: 關(guān)于面向構(gòu)件和EOS的一些思考-xml和元數(shù)據(jù)解決了接口脆弱性問題嗎? 2005-06-30 09:11 emu
          其實用xml實現(xiàn)的“總線”還不也相當(dāng)于一個“全局函數(shù)”?

          硬編碼的map 的key我想可以分離到代碼之外,用配置文件來解決一部分hardcode的問題,它帶來的問題不會比xml更多。

          周末重新考慮了一下,我覺得這樣一個全局的數(shù)據(jù)存放區(qū)域或者“數(shù)據(jù)總線”對于構(gòu)件直接的解耦是很有幫助的,事實上我想不出更靈活更好的方式。本來想寫篇日記的,后來發(fā)現(xiàn)很多自以為很獨(dú)到的想法在《業(yè)務(wù)構(gòu)件工廠》中都早已被前人全面的考慮過了,還是等抽出時間讀完這本書再發(fā)表我的瓜論吧。  回復(fù)  更多評論
            

          # re: 關(guān)于面向構(gòu)件和EOS的一些思考-xml和元數(shù)據(jù)解決了接口脆弱性問題嗎? 2005-07-23 11:15 emu
          嘻嘻,這篇隨筆居然上了七月的程序員雜志。  回復(fù)  更多評論
            


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 竹山县| 乌鲁木齐县| 衡水市| 华坪县| 拉萨市| 柳州市| 商都县| 内江市| 黄浦区| 黎平县| 彭水| 高邑县| 巢湖市| 平利县| 司法| 正宁县| 合阳县| 澎湖县| 屯留县| 开鲁县| 东台市| 文化| 手游| 延长县| 吉安县| 奉化市| 明星| 遵义市| 江都市| 房产| 云梦县| 靖宇县| 镇坪县| 大庆市| 玉溪市| 介休市| 绥棱县| 丰都县| 府谷县| 文安县| 英超|