日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

一文搞懂設(shè)計(jì)模式—享元模式

來(lái)源: 責(zé)編: 時(shí)間:2024-02-29 14:43:15 194觀看
導(dǎo)讀當(dāng)系統(tǒng)中存在大量相似對(duì)象時(shí),每個(gè)對(duì)象都需要占用一定的內(nèi)存空間,如果這些對(duì)象的大部分屬性是相同的,那么頻繁創(chuàng)建這些對(duì)象會(huì)導(dǎo)致內(nèi)存消耗過(guò)大。享元模式將這些相同部分抽取出來(lái)作為共享的內(nèi)部狀態(tài),在需要時(shí)進(jìn)行共享,從而減

當(dāng)系統(tǒng)中存在大量相似對(duì)象時(shí),每個(gè)對(duì)象都需要占用一定的內(nèi)存空間,如果這些對(duì)象的大部分屬性是相同的,那么頻繁創(chuàng)建這些對(duì)象會(huì)導(dǎo)致內(nèi)存消耗過(guò)大。享元模式將這些相同部分抽取出來(lái)作為共享的內(nèi)部狀態(tài),在需要時(shí)進(jìn)行共享,從而減少內(nèi)存占用。svF28資訊網(wǎng)——每日最新資訊28at.com

享元模式(Flyweight Pattern)是一種結(jié)構(gòu)型設(shè)計(jì)模式,旨在通過(guò)共享對(duì)象來(lái)最大化內(nèi)存利用和性能提升,享元模式嘗試重用現(xiàn)有的同類對(duì)象,如果未找到匹配的對(duì)象,則創(chuàng)建新對(duì)象。svF28資訊網(wǎng)——每日最新資訊28at.com

使用場(chǎng)景

  • 當(dāng)系統(tǒng)中存在大量相似對(duì)象且造成了內(nèi)存浪費(fèi)時(shí),可以考慮使用享元模式。
  • 對(duì)象的狀態(tài)可以外部化,并且剝離出共享部分和特有部分。
  • 需要緩沖池的場(chǎng)景。

享元模式在對(duì)象池中的使用是一種常見(jiàn)的場(chǎng)景,通過(guò)對(duì)象池管理和復(fù)用對(duì)象實(shí)例,可以提高系統(tǒng)性能和資源利用率。對(duì)象池通常用于緩存、連接池等場(chǎng)景,其中對(duì)象的創(chuàng)建成本較高或者頻繁創(chuàng)建銷毀會(huì)影響性能時(shí),對(duì)象池就顯得尤為重要。svF28資訊網(wǎng)——每日最新資訊28at.com

在 Java 中,String 類的 intern() 方法是享元模式的一個(gè)應(yīng)用。intern() 方法返回字符串對(duì)象的規(guī)范化表示形式,即返回字符串池中與調(diào)用字符串等效的字符串。如果字符串池中已經(jīng)存在等效的字符串,則返回該字符串;否則,將此字符串添加到字符串池中,并返回新的字符串引用。svF28資訊網(wǎng)——每日最新資訊28at.com

下面是一個(gè)示例代碼,演示了 String 類的 intern() 方法的應(yīng)用:svF28資訊網(wǎng)——每日最新資訊28at.com

public class StringInternExample {    public static void main(String[] args) {        String str1 = "hello";        String str2 = new String("hello");        String str3 = str2.intern();        System.out.println("str1 == str2: " + (str1 == str2)); // false        System.out.println("str1 == str3: " + (str1 == str3)); // true    }}

在上述示例中,str1 和 str2 是兩個(gè)不同的字符串對(duì)象,盡管它們的值相同,但由于 str2 使用了 new String() 構(gòu)造方法創(chuàng)建,在堆內(nèi)存中會(huì)生成一個(gè)新的對(duì)象。而通過(guò)調(diào)用 intern() 方法后,str3 返回的是字符串池中已存在的字符串對(duì)象,因此 str1 和 str3 指向的是同一個(gè)對(duì)象,所以輸出結(jié)果為 "str1 == str3: true"。這就是 intern() 方法的享元模式應(yīng)用,避免了重復(fù)創(chuàng)建相同的字符串對(duì)象,節(jié)省了內(nèi)存空間。svF28資訊網(wǎng)——每日最新資訊28at.com

具體實(shí)現(xiàn)

享元模式包含以下幾個(gè)角色:svF28資訊網(wǎng)——每日最新資訊28at.com

  • 抽象享元(Flyweight): 定義了享元對(duì)象的外部狀態(tài)和內(nèi)部狀態(tài),通過(guò)這個(gè)抽象類可以接受并作用于外部狀態(tài)。
  • 具體享元(Concrete Flyweight): 繼承了抽象享元類,包含內(nèi)部狀態(tài)和外部狀態(tài)。具體享元對(duì)象需要確保內(nèi)部狀態(tài)是可以共享的,同時(shí)提供操作外部狀態(tài)的方法。
  • 非共享具體享元(Unshared Concrete Flyweight): 與共享具體享元相對(duì)應(yīng),非共享具體享元是不能被共享的享元對(duì)象,通常是在具體享元中無(wú)法共享的情況下使用。
  • 享元工廠(Flyweight Factory): 負(fù)責(zé)創(chuàng)建和管理享元對(duì)象,在請(qǐng)求時(shí)返回已經(jīng)創(chuàng)建的享元對(duì)象實(shí)例或者新創(chuàng)建一個(gè)享元對(duì)象。享元工廠通常會(huì)維護(hù)一個(gè)享元池用于存儲(chǔ)已經(jīng)創(chuàng)建的享元對(duì)象。

在享元模式中,核心在于區(qū)分內(nèi)部狀態(tài)和外部狀態(tài)。內(nèi)部狀態(tài)是可以共享的部分,而外部狀態(tài)是對(duì)象的非共享部分。svF28資訊網(wǎng)——每日最新資訊28at.com

  • 內(nèi)部狀態(tài)(Intrinsic State): 內(nèi)部狀態(tài)是享元對(duì)象固有的、可以共享的狀態(tài),它存儲(chǔ)在享元對(duì)象內(nèi)部并且不會(huì)隨著外部環(huán)境的變化而改變。內(nèi)部狀態(tài)可以被多個(gè)享元對(duì)象共享,因此通常將其設(shè)計(jì)為不可變的屬性。內(nèi)部狀態(tài)對(duì)于享元對(duì)象的具體實(shí)現(xiàn)是必需的,但不會(huì)隨著外部環(huán)境的變化而改變。
  • 外部狀態(tài)(Extrinsic State): 外部狀態(tài)是享元對(duì)象的可變部分,它隨著外部環(huán)境的變化而變化,需要通過(guò)客戶端傳入享元對(duì)象來(lái)進(jìn)行處理。外部狀態(tài)并不影響享元對(duì)象的內(nèi)部結(jié)構(gòu)或行為,它只是作為享元對(duì)象行為的參數(shù)或上下文信息傳入。外部狀態(tài)具有固化特性,不應(yīng)該隨內(nèi)部狀態(tài)改變而改變,否則導(dǎo)致系統(tǒng)的邏輯混亂。

通過(guò)區(qū)分內(nèi)部狀態(tài)和外部狀態(tài),享元模式實(shí)現(xiàn)了將對(duì)象的共享部分和變化部分分離的目的,有效地減少了系統(tǒng)中重復(fù)對(duì)象的數(shù)量,提高了系統(tǒng)的性能和資源利用率。內(nèi)部狀態(tài)是享元對(duì)象本身的屬性,而外部狀態(tài)則是根據(jù)具體情況動(dòng)態(tài)變化的參數(shù)。svF28資訊網(wǎng)——每日最新資訊28at.com

實(shí)現(xiàn)步驟和示例代碼如下:svF28資訊網(wǎng)——每日最新資訊28at.com

1.首先定義抽象享元角色。svF28資訊網(wǎng)——每日最新資訊28at.com

public abstract class Flyweight {    //內(nèi)部狀態(tài)    private String intrinsic;    //外部狀態(tài)    protected final String extrinsic;    //要求享元角色必須接受外部狀態(tài)    public Flyweight(String extrinsic){        this.extrinsic = extrinsic;    }    //定義業(yè)務(wù)操作    public abstract void operate();    //內(nèi)部狀態(tài)的getter/setter    public String getIntrinsic() {        return intrinsic;    }    public void setIntrinsic(String intrinsic) {        this.intrinsic = intrinsic;    }}

抽象享元角色一般為抽象類,它是描述一類事物的方法。svF28資訊網(wǎng)——每日最新資訊28at.com

2.具體享元角色。svF28資訊網(wǎng)——每日最新資訊28at.com

public class ConcreteFlyweight1 extends Flyweight{    //接受外部狀態(tài)    public ConcreteFlyweight1(String extrinsic){        super(extrinsic);    }    //根據(jù)外部狀態(tài)進(jìn)行邏輯處理    public void operate(){    //業(yè)務(wù)邏輯    }}
public class ConcreteFlyweight2 extends Flyweight{    //接受外部狀態(tài)    public ConcreteFlyweight2(String extrinsic){        super(extrinsic);    }    //根據(jù)外部狀態(tài)進(jìn)行邏輯處理    public void operate(){    //業(yè)務(wù)邏輯    }}

具體享元角色實(shí)現(xiàn)自己的業(yè)務(wù)邏輯,然后接收外部狀態(tài),以便內(nèi)部業(yè)務(wù)邏輯對(duì)外部狀態(tài)的依賴。svF28資訊網(wǎng)——每日最新資訊28at.com

3.享元工廠。svF28資訊網(wǎng)——每日最新資訊28at.com

public class FlyweightFactory {    //定義一個(gè)池容器    private static Map<String, Flyweight> pool = new HashMap<>();    //享元工廠    public static Flyweight getFlyweight(String extrinsic) {        //需要返回的對(duì)象        Flyweight flyweight;        //在池中沒(méi)有該對(duì)象        if (pool.containsKey(extrinsic)) {            flyweight = pool.get(extrinsic);        } else {            //根據(jù)外部狀態(tài)創(chuàng)建享元對(duì)象            flyweight = new ConcreteFlyweight1(extrinsic);            //放置到池中            pool.put(extrinsic, flyweight);        }        return flyweight;    }}

4.客戶端調(diào)用svF28資訊網(wǎng)——每日最新資訊28at.com

public static void main(String[] args) {        Flyweight flyweight1 = FlyweightFactory.getFlyweight("hello world");        System.out.println(flyweight1.hashCode());        Flyweight flyweight2 = FlyweightFactory.getFlyweight("hello world");        System.out.println(flyweight2.hashCode());    }    Output:    1705736037    1705736037

可以發(fā)現(xiàn)對(duì)象打印的 hashCode 一致,說(shuō)明對(duì)象得到了復(fù)用。svF28資訊網(wǎng)——每日最新資訊28at.com

Tips:外部狀態(tài)最好以Java的基本類型作為標(biāo)志,如String、int等,可以大幅地提升效率。如果使用自己編寫的類作為外部狀態(tài),則必須覆寫equals方法和hashCode方法,否則會(huì)出現(xiàn)通過(guò)鍵值搜索失敗的情況,例如map.get(object)、map.contains(object)等會(huì)返回失敗的結(jié)果。svF28資訊網(wǎng)——每日最新資訊28at.com

線程安全問(wèn)題

享元模式在多線程環(huán)境下可能存在線程安全問(wèn)題,主要原因是享元對(duì)象的內(nèi)部狀態(tài)和外部狀態(tài)被多個(gè)線程共享和修改,可能導(dǎo)致數(shù)據(jù)競(jìng)爭(zhēng)和不一致性。具體來(lái)說(shuō),如果多個(gè)線程同時(shí)嘗試修改同一個(gè)享元對(duì)象的外部狀態(tài),就會(huì)引發(fā)線程安全問(wèn)題。svF28資訊網(wǎng)——每日最新資訊28at.com

下面是示例代碼:svF28資訊網(wǎng)——每日最新資訊28at.com

public static void main(String[] args) {        for (int i = 0; i < 10; i++) {            new Thread(() -> {                Flyweight flyweight1 = FlyweightFactory.getFlyweight("hello world");                Flyweight flyweight2 = FlyweightFactory.getFlyweight("hello world");                System.out.println(flyweight1 == flyweight2);            }).start();        }    }Output:truefalsetruetruetruetruetruetruetruetrue

這段代碼展示了多線程環(huán)境下使用享元模式的示例。在 main 方法中,通過(guò)循環(huán)創(chuàng)建了 10 個(gè)線程,在每個(gè)線程中嘗試獲取表示 "hello world" 的享元對(duì)象,并比較兩個(gè)獲取的對(duì)象是否相等。svF28資訊網(wǎng)——每日最新資訊28at.com

可以觀察到輸出中存在 false,說(shuō)明對(duì)象不一樣了,存在線程安全問(wèn)題。svF28資訊網(wǎng)——每日最新資訊28at.com

要想實(shí)現(xiàn)線程安全,需要對(duì)享元工廠類稍加改造,代碼如下:svF28資訊網(wǎng)——每日最新資訊28at.com

public class FlyweightFactory {    //定義一個(gè)池容器    private static Map<String, Flyweight> pool = new ConcurrentHashMap<>();    //享元工廠    public static synchronized Flyweight getFlyweight(String extrinsic) {        Flyweight flyweight = pool.putIfAbsent(extrinsic, new ConcreteFlyweight1(extrinsic));        if (flyweight == null) {            return pool.get(extrinsic);        }        return flyweight;    }}

這樣就解決了線程安全問(wèn)題,不過(guò)性能上會(huì)有所降低,在需要的地方考慮一下線程安全即可,在大部分的場(chǎng)景下都不用考慮。svF28資訊網(wǎng)——每日最新資訊28at.com

總結(jié)

享元模式通過(guò)共享相似對(duì)象來(lái)減少內(nèi)存消耗,提高系統(tǒng)性能。它適用于存在大量相似對(duì)象且造成內(nèi)存浪費(fèi)的場(chǎng)景,但需要注意對(duì)內(nèi)部狀態(tài)和外部狀態(tài)的管理。合理應(yīng)用享元模式可以有效優(yōu)化系統(tǒng)架構(gòu),提升性能。svF28資訊網(wǎng)——每日最新資訊28at.com

優(yōu)點(diǎn)svF28資訊網(wǎng)——每日最新資訊28at.com

  • 大幅減少內(nèi)存使用,提高系統(tǒng)性能,實(shí)現(xiàn)了對(duì)象的復(fù)用,節(jié)約資源。
  • 在一定程度上實(shí)現(xiàn)了對(duì)象狀態(tài)的外部化,方便對(duì)對(duì)象狀態(tài)的管理和維護(hù)。

缺點(diǎn)svF28資訊網(wǎng)——每日最新資訊28at.com

  • 對(duì)象狀態(tài)的外部化可能導(dǎo)致系統(tǒng)不穩(wěn)定,需要謹(jǐn)慎設(shè)計(jì)。
  • 提高了系統(tǒng)的復(fù)雜度,需要分離出外部狀態(tài)和內(nèi)部狀態(tài),而且外部狀態(tài)具有固有化的性質(zhì),不應(yīng)該隨著內(nèi)部狀態(tài)的變化而變化,否則會(huì)造成系統(tǒng)的混亂。

本文鏈接:http://www.www897cc.com/showinfo-26-75345-0.html一文搞懂設(shè)計(jì)模式—享元模式

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 前端開(kāi)發(fā):Visual Studio Code和Visual studio如何選?

下一篇: 六大前端自動(dòng)化測(cè)試框架推薦,提升你的開(kāi)發(fā)效率與質(zhì)量

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 紅魔電競(jìng)平板評(píng)測(cè):大屏幕硬實(shí)力

    前言:三年的疫情因?yàn)橐暇W(wǎng)課的原因激活了平板市場(chǎng),如今網(wǎng)課的時(shí)代已經(jīng)過(guò)去,大家的生活都恢復(fù)到了正軌,這也就意味著,真正考驗(yàn)平板電腦生存的環(huán)境來(lái)了。也就是面對(duì)著這種殘酷的
  • 2023 年的 Node.js 生態(tài)系統(tǒng)

    隨著技術(shù)的不斷演進(jìn)和創(chuàng)新,Node.js 在 2023 年達(dá)到了一個(gè)新的高度。Node.js 擁有一個(gè)龐大的生態(tài)系統(tǒng),可以幫助開(kāi)發(fā)人員更快地實(shí)現(xiàn)復(fù)雜的應(yīng)用。本文就來(lái)看看 Node.js 最新的生
  • 不容錯(cuò)過(guò)的MSBuild技巧,必備用法詳解和實(shí)踐指南

    一、MSBuild簡(jiǎn)介MSBuild是一種基于XML的構(gòu)建引擎,用于在.NET Framework和.NET Core應(yīng)用程序中自動(dòng)化構(gòu)建過(guò)程。它是Visual Studio的構(gòu)建引擎,可在命令行或其他構(gòu)建工具中使用
  • 一篇聊聊Go錯(cuò)誤封裝機(jī)制

    %w 是用于錯(cuò)誤包裝(Error Wrapping)的格式化動(dòng)詞。它是用于 fmt.Errorf 和 fmt.Sprintf 函數(shù)中的一個(gè)特殊格式化動(dòng)詞,用于將一個(gè)錯(cuò)誤(或其他可打印的值)包裝在一個(gè)新的錯(cuò)誤中。使
  • 虛擬鍵盤 API 的妙用

    你是否在遇到過(guò)這樣的問(wèn)題:移動(dòng)設(shè)備上有一個(gè)固定元素,當(dāng)激活虛擬鍵盤時(shí),該元素被隱藏在了鍵盤下方?多年來(lái),這一直是 Web 上的默認(rèn)行為,在本文中,我們將探討這個(gè)問(wèn)題、為什么會(huì)發(fā)生
  • 騰訊蓋樓,字節(jié)拆墻

    來(lái)源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之&ldquo;想重溫暴刷深淵、30+技能搭配暴搓到爽的游戲體驗(yàn)嗎?一起上晶核,即刻暴打!&rdquo;曾憑借直播騰訊旗下代理格斗游戲《DNF》一
  • 消息稱小米汽車開(kāi)始篩選交付中心:需至少120個(gè)車位

    IT之家 7 月 7 日消息,日前,有微博簡(jiǎn)介為“汽車行業(yè)從業(yè)者、長(zhǎng)三角一體化擁護(hù)者”的微博用戶 @長(zhǎng)三角行健者 發(fā)文表示,據(jù)經(jīng)銷商集團(tuán)反饋,小米汽車目前
  • OPPO K11搭載高性能石墨散熱系統(tǒng):旗艦同款 性能涼爽釋放

    日前OPPO官方宣布,將于7月25日14:30舉辦新品發(fā)布會(huì),屆時(shí)全新的OPPO K11將正式與大家見(jiàn)面,將主打旗艦影像,和同檔位競(jìng)品相比,其最大的賣點(diǎn)就是將配備索尼
  • 機(jī)構(gòu)稱Q2全球智能手機(jī)出貨量同比下滑11% 蘋果份額依舊第2

    7月20日消息,據(jù)外媒報(bào)道,研究機(jī)構(gòu)的報(bào)告顯示,由于需求下滑,今年二季度全球智能手機(jī)的出貨量,同比下滑了11%,三星、蘋果等主要廠商的銷量,較去年同期均有下
Top 主站蜘蛛池模板: 雅安市| 平原县| 靖西县| 四川省| 姜堰市| 冷水江市| 台江县| 昌都县| 潮州市| 平阴县| 崇明县| 山西省| 金门县| 同仁县| 定结县| 麦盖提县| 义马市| 温泉县| 吉水县| 天全县| 新源县| 定边县| 东乌珠穆沁旗| 嘉祥县| 化州市| 舒城县| 湖州市| 福清市| 松溪县| 清流县| 张家川| 井陉县| 黄龙县| 紫云| 奎屯市| 金塔县| 泸溪县| 彰化县| 庆安县| 织金县| 保康县|