1. 程式人生 > >Java設計模式——享元模式

Java設計模式——享元模式

概述

在有大量物件時,有可能會造成記憶體溢位,我們把其中共同的部分抽象出來,如果有相同的業務請求,直接返回在記憶體中已有的物件,避免重新建立。

版權說明

目錄

享元模式

定義

享元模式是一種結構型模式,運用共享技術有效地支援大量細粒度的物件。

單純享元模式

在享元模式中,就其定義我們可以構建出單純的享元模式。下圖是單純享元模式的類圖:
這裡寫圖片描述

在單純的享元模式中,需要給出一個抽象介面,以規定出所有具體享元角色需要實現的方法。實現如下:
Flyweight.java

public interface Flyweight {
    public
void operation(String state); }

對於享元部分,ConcreteFlyweight 必須是可共享的,它儲存的任何狀態都必須是內部(intrinsic),ConcreteFlyweight 必須和它的應用環境場合無關。比如字串 “Hello” 就無需關心使用它的場合,它是一個不可變的物件。
ConcreteFlyweight.java

public class ConcreteFlyweight implements Flyweight {

    private String intrinsicState = null;

    /**
     * 建構函式 內蘊狀態作為引數傳入
     */
public ConcreteFlyweight(String _intrinsicState) { this.intrinsicState = _intrinsicState; } /** * 外蘊狀態作為引數傳入方法中 改變方法的行為 但是並不改變物件的內蘊狀態 */ @Override public void operation(String extrinsicState) { System.out.println("內蘊狀態:" + intrinsicState); System.out.println("外蘊狀態:"
+ extrinsicState); } }

在享元模式中,有一個至關重要的模組就是工廠模組了。在 Flyweight Factory 裡維護了一個 Flyweight 池(存放內部狀態),Flyweight Factory 就是通過這個 Flyweight 池對整個享元模式進行控制。
FlyweightFactory.java

public class FlyweightFactory {

    private Map<Integer, Flyweight> labels = new HashMap<Integer, Flyweight>();

    public Flyweight factory(String intrinsicState) {

        int hashCode = intrinsicState.hashCode();

        Flyweight fly = labels.get(hashCode);

        if (fly == null) {
            fly = new ConcreteFlyweight(intrinsicState);
            labels.put(hashCode, fly);
        }

        return fly;
    }
}

在上面的工廠模組中可以看到,FlyweightFactory 實際上是起到了一個過濾篩選的功能,過濾重複的物件,快取新物件。

不共享的享元模式

與共享的享元物件相對的就是不共享的享元物件。關於不共享的享元物件,可能你會有一些疑問,既然不共享,為何還要包含到享元模式中來呢?這可能是出於完整性的考慮,或是要某些場景下既要使用共享的享元,又要使用不共享的享元吧。關於這一點本人也還沒有完全理解,也有可能根本不需要這一個不共享的享元物件吧。下面是不共享的享元類圖:
這裡寫圖片描述

不共享的享元實現與 ConcreteFlyweight 無異。如下:
UnsharedConcreteFlyweight.java

public class UnsharedConcreteFlyweight implements Flyweight {

    private String intrinsicState = null;

    public UnsharedConcreteFlyweight(String _intrinsicState) {
        this.intrinsicState = _intrinsicState;
    }

    @Override
    public void operation(String extrinsicState) {
        System.out.println("內蘊狀態:" + intrinsicState);
        System.out.println("外蘊狀態:" + extrinsicState);
    }
}

下面是對單純的享元與不共享的享元進行測試的程式碼。
Client.java

public class Client {

    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();

        Flyweight fly1 = factory.factory("Hello");
        fly1.operation("ExtrinsicState-1");

        Flyweight fly2 = factory.factory("DesignPattern");
        fly2.operation("ExtrinsicState-2");

        Flyweight fly3 = factory.factory("Flyweight");
        fly3.operation("ExtrinsicState-3");

        Flyweight fly4 = factory.factory("Hello");
        fly4.operation("ExtrinsicState-4");

        System.out.println("fly1 == fly2 ? " + (fly1 == fly2));
        System.out.println("fly1 == fly3 ? " + (fly1 == fly3));
        System.out.println("fly1 == fly4 ? " + (fly1 == fly4));

        Flyweight fly5 = new UnsharedConcreteFlyweight("Unshared");
        fly5.operation("ExtrinsicState-5");
    }
}
內蘊狀態:Hello
外蘊狀態:ExtrinsicState-1
內蘊狀態:DesignPattern
外蘊狀態:ExtrinsicState-2
內蘊狀態:Flyweight
外蘊狀態:ExtrinsicState-3
內蘊狀態:Hello
外蘊狀態:ExtrinsicState-4
fly1 == fly2 ? false
fly1 == fly3 ? false
fly1 == fly4 ? true
內蘊狀態:Unshared
外蘊狀態:ExtrinsicState-5

複合享元模式

在上面的單純享元中,所有的享元可以說是在同一個分組裡。有時候這樣的大集合可能並不能發揮出很好的應用功能,所以引入了複合式的享元模式。下面是複合式享元模式類圖:
這裡寫圖片描述

複合式享元相當於多個單純享元的集合。也就是說複合享元相當於對單純享元進行了一個再分組,在複合享元的每個分組裡又是一個獨立的單純享元模式。相關關鍵程式碼如下:
ConcreteCompositeFlyweight.java

public class ConcreteCompositeFlyweight implements Flyweight {

    private Map<Integer, Flyweight> labels = new HashMap<Integer, Flyweight>();

    public void add(int key, Flyweight flyweight) {
        labels.put(key, flyweight);
    }

    @Override
    public void operation(String extrinsicState) {
        Flyweight flyweight = null;
        for (Object key : labels.keySet()) {
            flyweight = labels.get(key);
            flyweight.operation(extrinsicState);
        }
    }
}

對於其構建工廠也需要進行重新設計,如下:
FlyweightFactory.java

public class FlyweightFactory {

    private Map<Integer, Flyweight> labels = new HashMap<Integer, Flyweight>();

    /**
     * 單純享元工廠
     */
    public Flyweight factory(String intrinsicState) {
         ... ...
         return fly;
    }

    /**
     * 複合享元工廠
     */
    public Flyweight compositeFactory(List<String> intrinsicStates) {
        ConcreteCompositeFlyweight flyweight = new ConcreteCompositeFlyweight();

        for (String intrinsicState : intrinsicStates) {
            flyweight.add(intrinsicState.hashCode(), factory(intrinsicState));
        }

        return flyweight;
    }
}

測試類
Client.java

public void compositeFlyweight() {
        List<String> intrinsicStates = new ArrayList<String>();
        intrinsicStates.add("Hello");
        intrinsicStates.add("Java");
        intrinsicStates.add("DesignPattern");
        intrinsicStates.add("Flyweight");

        FlyweightFactory factory = new FlyweightFactory();
        Flyweight flyweight1 = factory.compositeFactory(intrinsicStates);
        Flyweight flyweight2 = factory.compositeFactory(intrinsicStates);
        System.out.println("flyweight1 == flyweight2 ? " + (flyweight1 == flyweight2));

        flyweight1.operation("複合享元-1");
        flyweight2.operation("複合享元-2");
    }
flyweight1 == flyweight2 ? false
內蘊狀態:Java
外蘊狀態:複合享元-1
內蘊狀態:Flyweight
外蘊狀態:複合享元-1
內蘊狀態:Hello
外蘊狀態:複合享元-1
內蘊狀態:DesignPattern
外蘊狀態:複合享元-1
內蘊狀態:Java
外蘊狀態:複合享元-2
內蘊狀態:Flyweight
外蘊狀態:複合享元-2
內蘊狀態:Hello
外蘊狀態:複合享元-2
內蘊狀態:DesignPattern
外蘊狀態:複合享元-2

JDK 裡的享元模式

在 JDK 的設計裡,也有很享元模式。比如一些常量池的設計(String 常量池、Integer 常量池等等);

Ref

GitHub 原始碼下載

相關推薦

你所不知道的Java設計模式

享元模式(Flyweight Pattern): 運用共享技術有效地支援大量細粒度物件的複用,系統只使用少量物件,而這些物件都很相似,狀態變化很小,可以實現物件的多次複用。由於享元模式要求能夠共享的物件必須是細粒度物件,因此它又稱為輕量級模式,它是一種物件結構型模式。 當系統中存在大量相

重走Java設計模式——模式(Flyweight Pattern)

享元模式 定義 享元模式(Flyweight Pattern)主要用於減少建立物件的數量,以減少記憶體佔用和提高效能。這種型別的設計模式屬於結構型模式,它提供了減少物件數量從而改善應用所需的物件結構的方式。 程式碼示例 我們將建立一個 Shape介面和實現了

java常用設計模式--模式簡單例項

package com.ruanyun;import java.util.HashMap;import java.util.Map;/** * @Auther: maxw * @Date: 2018/11/21 09:47 * @Description:享元模式:“享”就是分享之意,指一物被眾人共享,而這也正

淺談Java設計模式——模式(Flyweight)

一、概述         運用共享技術有效地支援大量細粒度的物件。在一個系統中物件會使得記憶體佔用過多,特別是那些大量重複的物件,這就是對系統資源的極大浪費。享元模式對物件的重用提供了一種解決方案,它使用共享技術對相同或者相似物件實現重用。享元模式就是執行共享技術有效地支援

JAVA設計模式----模式

解釋一下概念:也就是說在一個系統中如果有多個相同的物件,那麼只共享一份就可以了,不必每個都去例項化一個物件。比如說一個文本系統,每個字母定一個物件,那麼大小寫字母一共就是52個,那麼就要定義52個物件。如果有一個1M的文字,那麼字母是何其的多,如果每個字母都定義一個物件那麼記憶體早就爆了。那麼如果要

JAVA 設計模式 模式

public class FlyweightPattern {     public static void main(String[] args) {         int extrinsicstates = 1;             FlywightFactory factory = new 

Java設計模式——模式

概述 在有大量物件時,有可能會造成記憶體溢位,我們把其中共同的部分抽象出來,如果有相同的業務請求,直接返回在記憶體中已有的物件,避免重新建立。 版權說明 目錄 享元模式 定義 享元模式是一種結構型模式,運用共享技

Java 設計模式 -- 模式

在介紹享元模式之前,先來看一個問題。假設要你去做一款撲克牌遊戲,你會針對撲克牌設計一種怎樣的資料結構呢? 因為撲克牌有四種花色,也即紅桃(Heart),黑桃(Spade),方塊(Diamond ),梅花(Club),有 13 種不同的大小,也即 A - K ,

Java設計模式——模式(Flyweight)

定義:物件結構型模式運用共享技術有效地支援大量細粒度的物件。 在面向物件程式設計中,有時候應用中建立的物件過多,導致儲存空間的不必要的浪費(一部分屬性是很多物件共享的,另一部分是每個物件根據自己的使用情況獨有的,但是每個物件都將所有的屬性全部進行建立,這樣即使是可共享的屬性

Java設計模式----模式(FlyWeight)

1.  享元模式定義:      享元模式是池技術的重要實現原理,定義如下:使用共享物件可以有效的支援大量的細粒度物件     內部狀態:儲存在享元物件內部不隨外部環境改變可以共享出來的資訊     外部狀態:外部狀態是物件得以依賴的一個標記,是隨外部環境改變而變化、不可以

淺談js設計模式模式

func 參數 如何 del 如果 性能優化 情況 under 核心 享元(flyweight)模式是一種用於性能優化的模式,“fly”在這裏是蒼蠅的意思,意為蠅量級。享元模式的核心是運用共享技術來有效支持大量細粒度的對象。 假設有個內衣工廠,目前的產品有 50種男式內衣和

設計模式——模式

.post 運行時間 AD 重復 this com 本地 方式 sign 享元模式定義 復用內存中已經存在的對象,降低重復創建對象的性能消耗。 享元模式 UML圖 享元共享技術 享元中內部狀態時共享的,Flyweight factory負責維護一個對象池(Flyweigh

設計模式-模式

設計模式 享元模式 場景:象棋中每粒子都是紅方兩顆黑方兩顆。比如:車,棋盤中總共有4個,常規做法是有4個對象,通過享元1個對象搞定。代碼如下: //棋子的外部狀態 class Protertys { public string name { get; set; }

PHP設計模式 - 模式

turn 客戶 有效 nds 一個 true urn cli crete 運用共享技術有效的支持大量細粒度的對象 享元模式變化的是對象的存儲開銷 享元模式中主要角色: 抽象享元(Flyweight)角色:此角色是所有的具體享元類的超類,為這些類規定出需要實現的公共接口

設計模式(28)-----結構型模式-----模式

享元模式(Flyweight Pattern)主要用於減少建立物件的數量,以減少記憶體佔用和提高效能。這種型別的設計模式屬於結構型模式,它提供了減少物件數量從而改善應用所需的物件結構的方式。 享元模式嘗試重用現有的同類物件,如果未找到匹配的物件,則建立新物件。我們將通過建立 5 個物件來畫出 20 個分佈於

設計模式-模式(Flyweight)

概述 定義 : 提供了減少物件數量從而改善應用所需的物件結構的方式 運用共享技術有效的支援大量細粒度的物件 型別 : 結構型 適用場景 常常應用於系統底層的開發, 以便解決系統的效能問題 系統有大量相似的物件, 需要緩衝池的場景

大話設計模式-模式

享元模式 運營共享技術有效地支援大量細粒度的物件。 享元模式的原理 享元模式可以避免大量非常相似類的開銷。在程式設計中,有時需要生成大量細粒度的類的例項來表示資料。 如果能發現這些例項除了幾個引數外基本都是相通的,有時就能夠大幅地減少需要例項化的類的數量。 如果能把那些引數移到類的例項的外面,在方法

移動開發之設計模式- 模式(IOS&Android)

資源 完全參照 享元模式|菜鳥教程 ,但不包括IOS程式碼 享元模式 享元模式(Flyweight Pattern)主要用於減少建立物件的數量,以減少記憶體佔用和提高效能。這種型別的設計模式屬於結構型模式,它提供了減少物件數量從而改善應用所需的物件結構的方式。 享元模式嘗試重用現

設計模式-模式-C++實現

享元模式:以共享的方式高效的支援大量的細粒度物件。通過複用記憶體中已存在的物件,降低系統建立物件例項的效能消耗。 享元模式關鍵是要區分外部狀態和內部狀態。 內部狀態:指的是物件本身的屬性,這些屬性不受外

javascript設計模式-模式(10)

享元模式是一種優化模式,它最適合解決因建立類似物件而涉及效能的問題。這種模式在js中尤其有用,因為複雜的js程式碼可能很快就會用光瀏覽器的所有可用記憶體。通過把大量獨立物件轉化為少量共享物件,可降