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

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

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

    我的隱式生活(My Implicit Life)

    繼續搞“對象”,玩OO.

    首頁 新隨筆 聯系 聚合 管理
      11 Posts :: 1 Stories :: 39 Comments :: 0 Trackbacks

    創建和銷毀對象

    重點關注對象的創建和銷毀:什么時候、如何創建對象,什么時候、什么條件下應該避免創建對象,如何保證對象在合適的方式下被銷毀,如何在銷毀對象之前操作一些必須的清理行為。

    嘗試用靜態工廠方法代替構造器

    如果一個 client 要實例化一個對象來使用,傻 b 都知道應該先調用類的構造器來 new 一個對象,之后再調用相應的方法。除了這個方式, Java Effective 還建議了另一種方法:用靜態工廠方法來提供一個類的實例。以下的例子不反映兩者的優劣,只是反映兩者在代碼實現上的不同,優劣之后再談:

    假設咱們要一個顏色為黑色、長度為 50cm 的錘子,自然就用構造器創建一個

    Hammer myHammer =? new Hammer(Color.BLACK, 50);

    而用靜態工廠方法來實例化一個對象,如下

    Hammer myHammer = Hammer.factory(Color.BLACK,50);

    也可以用專門的一個工廠類來實例化

    Hammer myHammer = Toolkit.factory(“Hammer”, Color.BLACK,50);??

    單純從上面的代碼上看,真的只有傻 b 才會選擇靜態工廠的方法,完全就是多此一舉,直接 new 又快又爽,搞這么麻煩做莫斯(武漢話“什么”的意思)?

    別急,別急,你急個莫 b (武漢粗話:基本就是“你急個毛”的意思)?

    下面就說說用靜態工廠代替構造器的好處( advantage )和不好處( disadvantage )。

    第一個好處,講你都不信,行家們認為,構造器有一個不好的地方就是:這個方法的簽名( signture )太固定了。

    構造器的名字是固定的,生個 Hammer ,構造器的名字就是 Hammer (……),唯一能變化的地方就是參數,假設我的這個錘子有兩個很變態的構造需要:

    1 :第一個參數是顏色( Color 型),第二個參數是錘子頭的重量( int 型)。

    Hammer Color c, int kg {

    //remainder omited

    }

    2 :第一個參數是顏色( Color 型),第二個參數是錘子的長度( int 型)。

    Hammer Color c, int cm {

    //remainder omited

    }

    感覺滿足需要了,但是細心一看,完了,構造器的參數列表類型重復了,肯定編譯通不過,這是面向對象構造器天生的缺陷——唯一的變化就是參數,參數都分辨不了,就真的分辨不了。

    而另外就算參數能分辨的了,構造器一多,它的參數一多,您根本就不知道每個參數是用來干什么的,只能去查閱文檔,在您已經眼花繚亂的時候再去查文檔,一個一個的對,折磨人的活。

    這個時候,您就可以考慮用靜態工廠方法來實例化對象了。因為靜態工廠方法有一個最簡單的特點就是:他有可以變化的方法名(構造器的名字變不了)。用名字的不同來代表不同的構造需要,這么簡單的普通的特點在這里就是它相對于構造器的 advantage

    如上面的錘子的例子可以這樣:

    1 Hammer.produceByWeight (Color c, int kg){

    //remainder omited

    }

    2 Hammer.produceByHeight (Color c, int cm){

    //remainder omited

    }

    這是不是一目了然多了。嗯,我是這樣認為的。

    第二個好處,“靜態工廠方法不需要每次都真的去實例化一個對象”——其實這也是另一些優化方法的前提。

    構造器的每次 invoke 必定會產生一個新的對象,而靜態工廠方法經過一定的控制,完全可以不用每次 invoke 都生成一個新的對象。

    為什么不每次都生成一個對象的原因就不必說了,因為原因太明顯。這個原因就是為什么要“共享”對象的原因。

    下面講講通常使用的兩種共享具體策略,也就是具體方法了:

    1 :單例模式的需要,一旦需要某個對象有單例的需要,必定對于這類對象的構造只能用靜態工廠方法了。

    2 flyweight 模式和不變( immutable 模式的需要,這兩個模式很多時候都說一起使用的,一旦一些對象我們認為是不變的,那自然就想拿來重用,也就說共享,而 flyweight 就是用來重用這些小粒度對象的。

    Boolean.valueOf (boolean) 方法:

    Boolean a = Boolean.valueOf (100);

    Boolean b = Boolean.valueOf (100);

    ?a,??b兩個引用都是指向同一個對象。

    這些對象都是不變的,而 valueOf 的控制就是用的 flyweight 方法。

    這種一個狀態(如上面一個數字)對應的對象只有一個還有一個好處,就是可以直接通過比較“引用”來判斷他們是否 equel (這里的 equel 是邏輯相等的意思),以前需要 a.equels(b) ,而一旦用“ flyweight 模式和不變( immutable 模式”后,避免了產生多余的相同對象,用 a==b 就可以達到 a.equels(b) 的目的了。這樣當然優化了 performance ??

    第三個好處,其實就是工廠方法的核心好處——我把它稱為“抽象類型構造器”。它可以為我們提供一個抽象類型的實例,同時必要的隱藏了抽象類型的具體結構。這是 new 怎么都達不到的。

    這種模式的好處其實就是面向對象的最核心的好處,抽象和具體可以分離,一旦抽象定義好了,具體的東西可以慢慢的變化,慢慢的拓展——開閉原則。

    Collections Framework API ,都是描述集合類型的接口,也就是對于客戶端來看,只有 Collection 這個類要認識,而實際上,實現這個接口的 Collection 是多種多樣的。如果要讓用戶都知道這些具體實現的 Collection ,就增加了復雜度。

    這時,通過一個靜態工廠方法,就可以隱藏各種 Collection 的具體實現,而讓 Client 只使用返回的 Collection 對象就可以了。

    這里還可以加上一些權限控制,如這些實現只要對于工廠來講是可以訪問的,不用是 public 的,而他們只要通過 public 的工廠就可以提供給用戶。非常有利于代碼的安全。

    靜態工廠方法的第一個缺點就是:使用靜態工廠方法創建的類的構造器經常都是非公共或非 protected 的。 這樣,以后這些類就沒有辦法被繼承了。不過也有人說,不用繼承就用 composition 唄。也是!呵呵。

    靜態工廠方法的第二個缺點是:在 jdk 文檔里,這些靜態工廠方法很難跟別的靜態方法相區別。 而文檔中,構造器是很容易看到的。

    為了一定程度解決這個問題,我們可以用一些比較特別的名字來給這類靜態工廠方法來命名。最常用的有:

    valueOf —— 用來放回跟參數“相同值”的對象。

    getInstance —— 返回一個對象的實例。單例模式中,就是返回單例對象。

    總結:靜態工廠方法和構造器都有各自的特點。最好在考慮用構造器之前能先考慮一下靜態工廠方法,往往,后者更有用一點。如果權衡了以后也看不出那個好用一些,那就用構造器,畢竟簡單本分多了。

    posted on 2006-07-15 12:35 marco 閱讀(625) 評論(0)  編輯  收藏 所屬分類: -=Java API=--=Java Techs=-
    主站蜘蛛池模板: 亚洲男人第一av网站| 亚洲黄色在线观看视频| 久久国产免费一区二区三区| 亚洲午夜未满十八勿入| 国产无人区码卡二卡三卡免费| 亚洲AV无码一区二区三区久久精品 | 亚洲男人的天堂在线va拉文| 久久狠狠躁免费观看2020| 亚洲中文字幕AV每天更新| 中文字幕不卡亚洲| 野花高清在线电影观看免费视频| 国产精品成人亚洲| 中文字幕亚洲精品资源网| 国产一级高清免费观看| 无码人妻久久一区二区三区免费| 亚洲AV无码成人网站在线观看| 亚洲欧洲在线观看| 亚洲成网777777国产精品| 18成禁人视频免费网站| 色多多A级毛片免费看| 亚洲国语在线视频手机在线| 亚洲国产精品毛片av不卡在线| 亚洲精品视频在线观看免费| a级毛片免费网站| 亚洲乱码av中文一区二区| 亚洲视频2020| 亚洲午夜福利精品久久 | 久久午夜免费视频| 日韩免费高清播放器| 国产精品亚洲а∨无码播放不卡 | 亚洲AV无码一区二区乱子仑 | 久久久无码精品亚洲日韩京东传媒| 亚洲av无码成人精品区在线播放| 97在线线免费观看视频在线观看| 国产一级一毛免费黄片| 综合偷自拍亚洲乱中文字幕| 亚洲欧洲日韩国产一区二区三区| 亚洲高清视频在线播放| 亚洲AV色香蕉一区二区| 亚洲午夜精品一级在线播放放| 国产美女做a免费视频软件|