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

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

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

    kapok

    垃圾桶,嘿嘿,我藏的這么深你們還能找到啊,真牛!

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      455 隨筆 :: 0 文章 :: 76 評論 :: 0 Trackbacks

    http://firebody.blogbus.com/logs/2004/08/338549.html

    轉自:javaeye論壇      作者:potian

    說明:這些帖子都是在討論工廠模式,容器配置,構造函數產生對象的方式各自優缺時的回帖。很不錯!感謝potian!!!

    除了靜態方法對具體子類的直接依賴問題之外,對象的產生封裝在對象內部也是一個很奇怪的想法,如果在不同情況下,例如需要同步或者需要lazy等等的話,你必須針對修改你的代碼,實際上我們最關心的是能夠在不同場合使用同一個對象的業務邏輯,而你這樣做的話會緊緊因為我們需要不同的對象創建方法而修改對象的代碼,這是非常不智的,這也是singleton被視作evil的重要原因之一。(例如singleton,有時候我們希望使用超類的實例,有時候希望使用子類的實例,有的時候我們希望產生單個,有的時候需要產生多個[取singleton單控制點的含義],有的時候需要同步,有的時候不需要同步,在集群的情況我們甚至可能需要數據庫來實現唯一化控制,有時候希望緩存,有的時候不需要緩存,有的時候希望增強,有的時候希望采用動態代理產生。所以一般來說,我們希望在一個系統內部最多只有一個入口的singleton,而我們也往往也不打算在其它不同的場合重用這個singleton)。

    代碼的重用是對他業務邏輯的重用,這正是對象的核心價值。所以如同charon所說的,相對而言,我們往往不在乎組裝代碼的重用性,而是追求業務代碼本身可以被按照不同的組裝方式使用,例如既可以在EJB下,也可以在普通的Java應用程序中,既可以作為遠程傳輸的對象,因此,我們往往不會去強制對象構造和產生的方式(例如由EJB容器產生,由IOC容器產生、有抽象工廠產生,或者直接由new產生),相反,是把對象的產生交給外部負責,這樣才能達到在不同場合下對象最大的可重用性。說個簡單的,如果對象的構造方法是私有的,那么現在的很多框架(例如hibernate,JavaBean,EJB等等你就根本不能使用了).這也是現在認為POJO比有特殊要求的對象更好的原因,因為任何一種框架和技術都可以自由選擇自己的方式來創建對象。

    所有創建型設計模式和IoC容器的使用正是基于這樣的假設的,只有對象把構造的責任交給外部來實現,那么我們才能有效地隱藏對象創建的時機、方式、方法,給不修改對象本身的代碼而能夠使用不同的對象創建方式(包括使用子類,替代類)提供了前提,從而提高對象實現業務邏輯的在不同場合的可重用性。所以不是說一定要用IOC容器或者用抽象工廠,而是可以用這些方法,也可以不用這種方法。而就抽象工廠和IoC容器本身而言,通過它們各自的封裝,可以進一步實現對不同具體實現子類的解綁,就更加好了。如果有一天你不想用Pico或者不想用抽象工廠,你可以選擇其他更加合適的方法來實現解綁。而這個責任不應該交給對象自己來實現,因為我們根本無法預料這個對象將會以什么樣的方式被構造出來,在什么時候構造出來,需要依賴什么其它外部機制構造出來(例如可能依賴數據庫,或者依賴串行化),這最好是有外部使用這個對象的環境來決定

    最終,我們希望能夠讓對象的創建、對象的銷毀完全脫離對象的使用,垃圾收集器已經為我們提供VM級別的支持,而抽象工廠和工廠方法以及其它構造型設計模式,IoC從模式和框架的角度給我們另一半。

    你這個已經是每次返回一個新的對象了,我要每次得到同一對象,我該怎么辦,你是不是叫我重新再在上面包一個類,把第一次取到的對象緩存起來,以后每次去取那個對象?這個時候你每次new一個還有什么意義,你說可以把它改成單個,那我原先在用的代碼怎么辦?

    再復雜一點,如果是需要在集群的服務器之間保持singleton,有的時候我需要用數據庫來持久對象狀態,通過數據庫來保持唯一性,那你這份代碼需要依賴于JDBC,這個時候如果一個普通的應用程序是不是也要依賴于JDBC?

    區別在于你的代碼是放在本類里面的,你這個類構造會直接依賴于你的環境和當前的假設,別人根本沒辦法重用你的類

    構造函數為什么沒有這些缺陷,因為我們可以通過另外一個類來實現和不同環境的結合,而我們正在談論的這個類本身可以在任何地方使用而不需要修改任何代碼.這是非常重要的,這是重用的基礎,從我們談的范圍內來說,如果對照OCP,那么它是C,一旦關閉,永不修改。構造函數為什么沒有這個問題,因為他自己不對任何構造自己的方法作出額外的假設(構造函數是最最近基本的假設了),而把構造的方法、意圖和時機完全交給了外部,如果對照OCP,那么它是O。除非你的靜態方法永遠等同于new,不然的話,你任何一種實現方式都是對可能的構造方式進行無意義的假設,會限制其他場合對你這份代碼重用的可能性,而如果永遠等于new,那你這個靜態方法還有什么用。

    舉例來說,假設有3個應用,對一個對象需要三種不同的構造方法,一個需要proxy以實現攔截,一個需要普通的java類做測試,另一個需要從數據庫里面讀取以保持集群之間的唯一性,我只需要對不同的環境寫不同的工廠,而不需要去改你那個嵌在業務代碼中的靜態方法,即使改了也不能同時重用于三個場合,你這個時候告訴我這是外部設計的決策. 和你的實現細節無關,我可以在外面去包一個類,那我要你那個靜態方法干什么,這個靜態方法里面到底是返回proxy還是普通java對象還是從數據庫里面讀取,任何一個都沒有意義

    總而言之,任何在本類內部假設自己將被如何、何時、以何種方式進行構造的代碼是極其不利于重用的(例如singleton就是一種限制重用的方法,只不過它由他自己適合的環境,因為任何系統里面肯定有一些類是可以重用,而有一些是特定于某個應用的)。因為你適合了一種環境的構造,必然會產生對另一種狀況的不適合,所以最好的方式是什么也不假設,把如何構造的責任傳遞給另外一個類或者框架,那個類可以結合具體的重用場合實現構造,緩存,單件化,動態代理等等它希望做的任何動作。

    面向對象的中心點是職責分離和變化頻率的分離,對一個希望被重用的對象來說,它的業務代碼是它變化頻率較低的部分(這是重用的基本假設),而由于目前各種不用容器、測試、分布式計算、事務處理等等場合的需要,它如何被構造的可能性則是一個比它本身業務邏輯變化率高得多的東西,這兩種職責必須被分離。


    至于你這種設計方法完全依賴于子類和繼承上的困難就更不用談了。你說你的大多數類不讓繼承,OO最重要的概念就是差異編程和增量編程,這是提高內外部質量、提高生產率的核心思想,如果沒有記錯的話,《面向對象軟件構造》第一章里面就明確地提出了幾個重要的內外部指標,也是整個OO思想的軟件工程基礎。


    posted on 2005-05-23 23:32 笨笨 閱讀(413) 評論(0)  編輯  收藏 所屬分類: J2EEALL軟件工程和項目管理
    主站蜘蛛池模板: 亚洲精品福利你懂| a级毛片免费全部播放| 亚洲国产成人影院播放| 国偷自产一区二区免费视频| 亚洲免费观看在线视频| 免费一级毛片在线播放不收费| 国产免费爽爽视频在线观看| 亚洲av日韩av综合| 中文亚洲AV片在线观看不卡| 麻豆一区二区免费播放网站 | 黄色网站软件app在线观看免费 | 在线观看免费黄色网址| 亚洲成人激情小说| 婷婷久久久亚洲欧洲日产国码AV | 美女被免费网站在线视频免费 | 两个人看的www高清免费视频| 亚洲区视频在线观看| 国产成人精品曰本亚洲79ren| A在线观看免费网站大全| 在线观看免费黄色网址| 国产成人亚洲精品电影| 亚洲狠狠ady亚洲精品大秀| 亚洲欧洲日产国码一级毛片| 久久久久久99av无码免费网站| 久久福利青草精品资源站免费| 羞羞漫画在线成人漫画阅读免费 | 亚洲13又紧又嫩又水多| 亚洲国产精品va在线播放| 四虎永久精品免费观看| 91在线品视觉盛宴免费| 久操视频免费观看| 国产精品免费久久久久久久久| 亚洲AV无码成人精品区日韩| 亚洲人成影院77777| 亚洲一区二区三区四区在线观看| 亚洲精品国产福利一二区| 成人午夜视频免费| 无码日韩人妻av一区免费| 久久久久av无码免费网 | 夜夜春亚洲嫩草影院| 亚洲AV无码专区日韩|