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

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

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

    細心!用心!耐心!

    吾非文人,乃市井一俗人也,讀百卷書,跨江河千里,故申城一游; 一兩滴辛酸,三四年學業,五六點粗墨,七八筆買賣,九十道人情。

    BlogJava 聯系 聚合 管理
      1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
    Gof 的書中指出,Flyweight的目的在於運用共享技術,使得一些細粒度的物件可以共享。

    Flyweight在牛津字典中的解釋是"boxer of the lightest class"。意思是特輕量級拳擊手?其實應該是取"the lightest class"這部份的解釋,一個特輕量級類別,這個類別所產生的物件可以共用在每一個場合(context),並依場合資訊表現物件外觀。

    在書中所舉出的例子是文檔編輯器中的字元物件,若每個字元物件會包括字元、大小、字型等等不同的資訊,想想一篇文章中可能出現多少字元,如果我們為每一個字元都使用一個物件來完整描述有關於它的訊息,那麼一篇文字中將會耗用多少的記憶體?!字元本身應可以共享,而大小、字型等等不同的資訊再分別設定。

    考慮數量多且性質相近的物件時,將該物件的資訊分為兩個部份:內部狀態(intrinsic)與外部狀態(extrinsic)。以上例來說,字元屬於內部狀態,而大小、字型等等不同的資訊屬於外部狀態。

    更詳細一些來說明,內部狀態是物件可共享的訊息部份,例如在繪製一個英文字串時,重覆的字元部份為內部狀態,像是 "ABC is BAC",其中A、B、C的字元資訊部份不必直接儲存於字元物件中,它是屬於可以共享的部份,可以將這些可以重複使用的字元儲存在Flyweight Pool中。

    外部狀態是物件依賴的一個場景(context),例如繪製字元時的字型資訊、位置資訊等等,繪製一個字元時,先從Flyweight Pool中找出共享的Flyweight,然後從場景中查找對應的繪製資訊(字型、大小、位置等)。

    其實任何學過Java的人就一定使用過Java中運用Flyweight模式的好處,要知道,如果您在程式中使用下面的方式來宣告,則實際上是指向同一個字串物件:
    String str1 = "flyweight";
    String str2 = "flyweight";
    System.out.println(str1 == str2);
     
    程式的執行結果會顯示True,在Java中,會維護一個String Pool,對於一些可以共享的字串物件,會先在String Pool中查找是否存在相同的String內容(字元相同),如果有就直接傳回,而不是直接創造一個新的String物件,以減少記憶體的耗用。

    再來個一看例子,String的intern()方法,我們來看看它的API說明的節錄:
    Returns a canonical representation for the string object.

    A pool of strings, initially empty, is maintained privately by the class String.

    When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

    這段話其實已說明了Flyweight模式的運作方式,用個實例來說明會更清楚:
    • Main.java
    public class Main { 
    public static void main(String[] args) {
    String str1 = "fly";
    String str2 = "weight";
    String str3 = "flyweight";
    String str4;

    str4 = str1 + str2;
    System.out.println(str3 == str4);

    str4 = (str1 + str2).intern();
    System.out.println(str3 == str4);
    }
    }

    在程式中第一次比較str3與str4物件是否為同一物件時,您知道結果會是false,而intern()方法會先檢查 String Pool中是否存在字元部份相同的字串物件,如果有的話就傳回,由於程式中之前已經有"flyweight"字串物件,intern()在String Pool中發現了它,所以直接傳回,這時再進行比較,str3與str4所指向的其實是同一物件,所以結果會是true。

    Flyweight模式在傳回物件時,所使用的是工廠模式,使用者並不會知道物件被創造的細節,下圖是Flyweight模式的結構圖:
    Flyweight

    之前舉的例子是針對物件的內部狀態所作的說明,那麼字型資訊等外部的設定呢?一兩個簡單的外部資訊設定可以直接寫死(hard code)在程式中,例如簡單的使用介面字型設定。

    但如果是文書處理器呢?使用者設定字型、大小等資訊會是動態的呢?Gof書中將字型資訊作為是繪製字元的外部狀態,使用一個Context 物件來維護外部狀態資料庫,每次要繪製字元物件時,這個Context物件會被作為參數傳遞給字元物件,字元物件透過查找Context中的資料來獲得字型資訊,從而進行正確的場景繪製。

    外部狀態維護與內部狀態之間的對應關係,在查找時,Gof書中所使用的是BTree?結構,由於查找必須花費時間,所以這也指出了使用Flyweight 模式所必須付出的代價:以時間換取空間。如何設計外部狀態的資料結構,以使得查找時間縮短,這是另一個重要的課題(不過就不是這篇文章要討論的課題了)。

    補充:關於字元(內部狀態)及字型、大小(外部狀態)之間的對應問題通常不太需要程式設計人員的關心,因為通常可以找的到一些現成的圖型介面API,它們都設計好一些相關元件,直接使用就可以了。
    posted on 2007-04-17 10:44 張金鵬 閱讀(280) 評論(0)  編輯  收藏 所屬分類: Structural 模式
    主站蜘蛛池模板: 免费国产成人午夜私人影视| 成全动漫视频在线观看免费高清版下载 | 久久久久亚洲精品影视| 亚洲综合视频在线| 亚洲精品视频久久久| 国产啪精品视频网免费| 在线观看特色大片免费网站| 人人爽人人爽人人片A免费 | 亚洲熟妇av一区二区三区漫画| 国产亚洲精品仙踪林在线播放| 永久免费的网站在线观看| 久久99精品免费一区二区| 亚洲免费视频一区二区三区| 亚洲AV无码一区二区大桥未久 | 亚洲美女自拍视频| 亚洲视频在线一区| 免费下载成人电影| 免费特级黄毛片在线成人观看 | 又大又黄又粗又爽的免费视频| 亚洲国产日韩a在线播放| 曰批全过程免费视频观看免费软件| 51在线视频免费观看视频| 欧洲乱码伦视频免费国产| 亚洲Av无码一区二区二三区| 香蕉免费在线视频| 国产人成免费视频网站| 添bbb免费观看高清视频| 夜夜亚洲天天久久| 美女被羞羞网站免费下载| 久久免费精品一区二区| 国产aa免费视频| 亚洲爆乳无码专区| 青娱乐在线视频免费观看| xxxx日本免费| 亚洲va久久久噜噜噜久久| 欧美日韩亚洲精品| 国产人成免费视频网站| 亚洲第一页在线播放| 8888四色奇米在线观看免费看| 99精品视频在线观看免费专区| 十八禁视频在线观看免费无码无遮挡骂过 |