<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 80,comments - 749,trackbacks - 2
    又是很久沒有寫Blog了,這兩天大量的時間貢獻給了兩件事,一是看Eclipse的源代碼(工作需要),二是不斷回復以前寫的文章的評論。今天請了假, 抽了點時間來討論討論重構。下面寫的東西您可能不太贊同,可能沒有遇到,也可能有其它更好的辦法,而我的觀點來自于我對Eclipse源代碼的理解和感 悟,無論您有什么想法請評論告訴我,不甚感謝。

    1。如果讓您隨手寫一個類,多半人會寫出一個以名詞命名的類,是的,我們的軟件中大量的類是以名詞來命名的。一個名詞表明了一組對象的共同類型,那么這個類型一定包括該組對象的共同屬性和共同方法。

    2。在幾次迭代之后我們發現類的屬性和方法都增多起來,這種粗放型的發展不利于軟件系統的整體結構。而事實上,有很多類在80%的時間只需用到20%的屬性代碼,而20%的時間卻需要用到80%的方法代碼,因此,將訪問率不同的屬性和方法分開是必然的趨勢。于是有了Descriptor模式,它將一個原始類分成屬性集中化和方法集中化的兩個類,屬性類的命名方式采用原類名+Descriptor的方式,方法類可能沿用原名稱,或重新取個名字以動詞命名。這種重構還有一個好處就是屬性類隨時可以加載,而方法類可能要到需要用時才懶加載。

    3。在經過多次迭代的增加該類的代碼之后,我們發現Descriptor類的屬性增多起來,過多的屬性使代碼變得重量化,同時使結構變得不清晰,一個擁有 過多屬性的類也會因知識過多而不易維護,此時最好的方法是將這個類分裂為兩個,或多個。分裂的方法也有橫向和縱向兩種。橫向的分裂使類變成兩個不同的類, 它們往往叫兩個不同的名字且都為名詞,同時也可能互相持有對方(Change Unidirectional Association to Bidirectional

    4。縱向的分裂方法(Extract Class)往 往會將比較公共的部分分離取名為原類名+Model,另一個類名稱不變,Model類是后者的父類。加過Model以后的類輕磅了很多,更便于管理,責任 也更輕。至于哪些屬性應該放在父類界限不是很嚴格,通俗的辦法是和原類名緊密相關的(特有的)屬性應該留在原處,不是緊密相關的(特有的)放在Model 類,比如ID、Label什么的就應該放在Model類。

    5。上面的方法反復用幾次,屬性集中的類就會變得越來越多。這時軟件結構雖然看的很清晰,可是使用起來大為不便,因為很多相關的屬性可能會在同一個場合下使用,而它們的實體卻可能分布在不同的對象中。解決這個問題的方法只有增加接口的數量(Extract Interface),多使用一些小接口,每個小接口表達了一個方面的含義,使用者在使用這些小接口時無法觸及它的實體對象(Prototype), 這種方法的優劣性在于使用者對于架構的理解,如果用的好這種方法會顯現出很多面向方面的特性,如果用的不好則是畫蛇添足,導致了接口的泛濫(還記得Dll Hell嗎,Java是不是正在形成一個Interface Hell?Eclipse是不是正在形成一個Plugin Hell?)。

    6。在大量應用了方面接口之后,我們又面臨著這樣的問題,很多使用這些Model的人其實只是關心其中的一部分固定屬性,和幾個為數不多的固定方法,有時連重量級方法都不關心,只關心用以交互的查找型get方法,對于這些使用者,我們只需提供一個門面(Facade)即 可。一個Facade包括在一個Model類和Descriptor類的群體中提供一組可以找到任何一個屬性的線索,其中的每一個線索都開始于 Facade,結束于存放對應屬性的屬性類,且遵循“最常用到的屬性,其線索最短”的原則。因而Facade絕不僅僅是一個類,而是一個完整的體系結構。

    7。接下來還有一個持久化的問題。如果一個類型存在對一個復雜類型的引用,這個復雜類型很可能被深深的隱藏在Facade之后,而且很可能是個不可持久化 的類型,那么如果前者要持久化,它只能保存一個該復雜類型的關鍵碼,并在持久化喚醒時很容易通過某個服務取到該關鍵碼所對應的對象。這個復雜過程沒理由要 求Facade以外的類來完成,因此有了Reference模式(Change Value To Reference),即為那個復雜類型定義一個類,類名為原類名+Reference,其責任是保存原類型的關鍵碼和查找原類型的真實對象。Reference類通常定義為可持久化。該模式的另一個好處是不必要常常訪問Facade,因為一個Facade也有可能極其復雜。

    8。在分析完屬性集中化的類和類群之間的關系之后,我們來看看方法集中化的類。這個類也有可能面臨方法激增的問題,此時想把一個類拆分成多個可沒有拆分屬 性集中化的類那么容易了,因為它們往往相互調用,耦合度極高,但又不能不拆(還記得Kent Beck曾經說過的嗎,“如果一個類的責任超過三個,我們就必須把它拆開以保證每個類的責任都不超過三個”)!幸好我們有Delegate模式可 供選擇,一個方法類可以由它的訪問子和工作子兩個角色來完成,就像銷售部門和生產部門一樣。訪問子還以原類名來命名,但是它不做實際的工作,只作實際工作 的準備工作(比如收集信息)和后續工作(比如轉換結果),生產性的工作交給工作子完成,后者通常以原類名+Delegate命名。這樣做的另一個好處就是 Delegate類可能很重磅,并面臨大量的資源分配,因而可以懶加載。

    9。現在我們有了一個不錯的體系結構,它包括一些輕量級的類、類的關系和設計模式,但是,不要以為這些東西是開始時就設計好了的,即使神仙也做不到那樣,令人驚奇的是,它們都是從剛剛您寫的一個名詞開始的。^_^

    經常重構的泡泡

    posted on 2005-04-13 10:54 Brian Sun 閱讀(2627) 評論(4)  編輯  收藏 所屬分類: 軟件

    FeedBack:
    # re: 高級重構方法的連用
    2005-04-13 17:19 | tacyuko
    通宵3天的翻譯結束了,好開心啊
    看到你的長文,好郁悶啊  回復  更多評論
      
    # re: 高級重構方法的連用
    2005-04-13 21:00 | idior
    屬性擴展的現象在個人應用中還真不是那么明顯。在其他書上似乎也很少提到,泡泡個人感覺如何?(除了在eclpise)
    還有責任分配的那個模式gof叫做bridge。用XXXdelegate來取類名感覺會影響該類的重用性。(被限于XXX使用)  回復  更多評論
      
    # re: 高級重構方法的連用
    2005-04-14 17:26 | Brian Sun
    呵呵,謝謝指點,我也覺得delegate的使用確實有些局限,但是在Eclipse當中,情況是這樣的,在Eclipse中一個Action往往在窗體初始化時就需要關于它的很多屬性和特征,但是它的執行實體卻只有在用戶點擊觸發這個Action時才會被懶加載,所以一個Action會把自己的執行體包裝在一個ActionDelegate當中。還有什么問題,請指正。。。。謝謝!

    泡泡
      回復  更多評論
      
    # re: 高級重構方法的連用
    2007-06-21 13:38 | FrankShaka
    怎么以前沒發現你有這篇文章?

    在網上找了半天,好像只有你這里講到了Descriptor模式和Reference模式。現在Reference模式我用的很爽啊,哈哈。。。。。  回復  更多評論
      
    主站蜘蛛池模板: 久久99免费视频| 成人免费夜片在线观看| 久久精品免费视频观看| 久久精品国产亚洲麻豆| 两个人看的www免费视频中文| 日韩精品电影一区亚洲| 另类图片亚洲校园小说区| 日本中文一区二区三区亚洲| 农村寡妇一级毛片免费看视频| 波多野结衣视频在线免费观看 | 国产亚洲一区二区手机在线观看 | a级毛片免费在线观看| 亚洲综合另类小说色区色噜噜| 九九久久国产精品免费热6| 亚洲成人一区二区| 久久免费视频一区| 亚洲va久久久噜噜噜久久狠狠 | 国产91免费在线观看| xxx毛茸茸的亚洲| 午夜神器成在线人成在线人免费| 亚洲综合激情五月色一区| 免费无码黄网站在线观看| 污污免费在线观看| 国精无码欧精品亚洲一区| 8888四色奇米在线观看免费看| 亚洲在成人网在线看| 日韩视频免费在线| jizz在线免费观看| 亚洲日本香蕉视频观看视频| 最近中文字幕mv免费高清视频7 | 免费大黄网站在线观看| 中国一级特黄的片子免费| 亚洲黄色在线观看| 国产色婷婷精品免费视频| 久久国产福利免费| 亚洲日本国产乱码va在线观看| 日本免费v片一二三区| 国产午夜精品理论片免费观看| 亚洲综合丁香婷婷六月香| gogo全球高清大胆亚洲| 午夜无码A级毛片免费视频|