<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 享元設計模式 > 原文: [https://howtodoinjava.com/design-patterns/structural/flyweight-design-pattern/](https://howtodoinjava.com/design-patterns/structural/flyweight-design-pattern/) 根據 GoF 定義,**享元設計模式**可以使用對象共享來有效地支持大量細粒度對象。 權重是**共享對象**,可以同時在多個上下文中使用。 享元在每種情況下都充當獨立對象。 ## 1.何時使用享元設計模式 我們可以在以下情況下使用享元模式: * 當我們需要大量類似的對象時,這些對象只有幾個參數是唯一的,而大多數東西通常都是通用的。 * 我們需要通過創建更少的對象并將它們共享來控制大量對象的內存消耗。 ## 2.外部和固有屬性 享元物體本質上具有兩種屬性 - 內部屬性和外部屬性。 **固有**狀態屬性存儲/共享在享元對象中,并且與享元的上下文無關。 作為最佳實踐,我們應該使固有狀態[**不可變**](https://howtodoinjava.com/java/basics/how-to-make-a-java-class-immutable/) 。 **外部**狀態會隨著重量級環境的變化而變化,這就是為什么它們無法共享的原因。 客戶端對象保持外部狀態,它們需要在對象創建過程中將其傳遞給享元對象。 ![Flyweight Pattern](https://img.kancloud.cn/67/f9/67f961462185ff2f65ac1acfa546ee51_597x157.png) 享元模式 ## 3.享元模式的真實示例 * 假設我們有一個**筆**,可以加/不加**筆芯**。 筆芯可以是任何顏色,因此可以使用鋼筆創建具有 N 種顏色的圖形。 這里`Pen`可以是具有`refill`作為外部屬性的享元對象。 所有其他屬性(例如筆身,指針等)可以是所有筆所共有的固有屬性。 一支筆只能通過其筆芯顏色來區分,沒有別的。 所有需要訪問紅筆的應用模塊 - 都可以使用紅筆的同一實例(共享對象)。 僅當需要使用不同顏色的筆時,應用模塊才會從享元工廠要求另一只筆。 * 在編程中,我們可以將`java.lang.String`常量視為享元對象。 所有字符串都存儲在字符串池中,如果我們需要帶有某些內容的字符串,那么運行時將返回對該池中已存在的字符串常量的引用(如果有)。 * 在瀏覽器中,我們可以在網頁的多個位置使用圖片。 瀏覽器將僅加載一次圖像,而其他瀏覽器將重用緩存中的圖像。 現在圖像是相同的,但已在多個地方使用。 URL 是固有屬性,因為它是固定且可共享的。 圖像的位置坐標,高度和寬度是外部屬性,它們根據必須渲染的位置(上下文)而變化。 ## 4.享元設計模式示例 在給定的示例中,我們正在構建一個筆刷應用,客戶可以在這三種類型上使用畫筆 - `THICK`,`THIN`和`MEDIUM`。 所有粗(細或中等)畫筆將以完全相似的方式繪制內容 - 僅內容顏色會有所不同。 ```java public interface Pen { public void setColor(String color); public void draw(String content); } ``` ```java public enum BrushSize { THIN, MEDIUM, THICK } ``` ```java public class ThickPen implements Pen { final BrushSize brushSize = BrushSize.THICK; //intrinsic state - shareable private String color = null; //extrinsic state - supplied by client public void setColor(String color) { this.color = color; } @Override public void draw(String content) { System.out.println("Drawing THICK content in color : " + color); } } ``` ```java public class ThinPen implements Pen { final BrushSize brushSize = BrushSize.THIN; private String color = null; public void setColor(String color) { this.color = color; } @Override public void draw(String content) { System.out.println("Drawing THIN content in color : " + color); } } ``` ```java public class MediumPen implements Pen { final BrushSize brushSize = BrushSize.MEDIUM; private String color = null; public void setColor(String color) { this.color = color; } @Override public void draw(String content) { System.out.println("Drawing MEDIUM content in color : " + color); } } ``` 這里筆刷`color`是外部屬性,將由客戶端提供,否則`Pen`的所有內容都將保持不變。 因此,從本質上講,僅當顏色不同時,我們才會創建一定大小的筆。 一旦其他客戶或環境需要該筆的大小和顏色,我們將重新使用它。 ```java import java.util.HashMap; public class PenFactory { private static final HashMap<String, Pen> pensMap = new HashMap<>(); public static Pen getThickPen(String color) { String key = color + "-THICK"; Pen pen = pensMap.get(key); if(pen != null) { return pen; } else { pen = new ThickPen(); pen.setColor(color); pensMap.put(key, pen); } return pen; } public static Pen getThinPen(String color) { String key = color + "-THIN"; Pen pen = pensMap.get(key); if(pen != null) { return pen; } else { pen = new ThinPen(); pen.setColor(color); pensMap.put(key, pen); } return pen; } public static Pen getMediumPen(String color) { String key = color + "-MEDIUM"; Pen pen = pensMap.get(key); if(pen != null) { return pen; } else { pen = new MediumPen(); pen.setColor(color); pensMap.put(key, pen); } return pen; } } ``` 讓我們使用客戶端來測試重量輕的筆對象。 客戶端在這里創建了三支`THIN`筆,但在運行時它們只是一個瘦型的筆對象,并且與所有三個調用共享。 ```java public class PaintBrushClient { public static void main(String[] args) { Pen yellowThinPen1 = PenFactory.getThickPen("YELLOW"); //created new pen yellowThinPen1.draw("Hello World !!"); Pen yellowThinPen2 = PenFactory.getThickPen("YELLOW"); //pen is shared yellowThinPen2.draw("Hello World !!"); Pen blueThinPen = PenFactory.getThickPen("BLUE"); //created new pen blueThinPen.draw("Hello World !!"); System.out.println(yellowThinPen1.hashCode()); System.out.println(yellowThinPen2.hashCode()); System.out.println(blueThinPen.hashCode()); } } ``` 程序輸出。 ```java Drawing THICK content in color : YELLOW Drawing THICK content in color : YELLOW Drawing THICK content in color : BLUE 2018699554 //same object 2018699554 //same object 1311053135 ``` ## 5.常見問題 #### 5.1 單例模式和享元模式之間的區別 單例模式有助于我們僅在系統中維護一個對象。 換句話說,一旦創建了所需的對象,我們就無法創建更多對象。 我們需要在應用的所有部分中重用現有對象。 當我們必須根據客戶端提供的外部屬性創建大量不同的相似對象時,將使用享元模式。 #### 5.2 并發對享元的影響 類似于單例模式,如果我們在并發環境中創建享元對象,則最終可能會遇到同一個享元對象的多個實例,這是不希望的。 要解決此問題,我們需要在創建享元時使用[單例模式](https://howtodoinjava.com/design-patterns/creational/singleton-design-pattern-in-java/)中使用的**雙檢鎖**。 #### 5.3 享元設計模式的好處 使用享元裝置,我們可以: * 減少可以相同控制的重物的內存消耗。 * 減少系統中“完整但相似的對象”的總數。 * 提供了集中機制來控制許多“虛擬”對象的狀態。 #### 5.4 內部和外部數據可以共享嗎? 內部數據是可共享的,因為它是所有上下文通用的。 不共享外部數據。 客戶需要將信息(狀態)傳遞給飛錘,這是其上下文所特有的。 #### 5.5 享元模式的挑戰 * 我們需要花一些時間來配置這些享元。 最初,設計時間和技能可能是開銷。 * 為了創建重量級,我們從現有對象中提取一個通用的模板類。 附加的編程層可能很棘手,有時很難調試和維護。 * 享元模式通常與單例工廠實現結合使用,并且為了保護奇點,需要額外的成本。 在評論中向我發送有關**享元模式**的問題。 學習愉快!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看