蘇州網(wǎng)站建設(shè)點(diǎn)一點(diǎn)公司網(wǎng)站設(shè)計(jì)模板
目錄
- 一、 啥是享元模式?
- 二、 為什么要用享元模式?
- 三、 享元模式的實(shí)現(xiàn)方式
- 四、 享元模式的優(yōu)缺點(diǎn)
- 五、 享元模式的應(yīng)用場(chǎng)景
- 六、 總結(jié)
🌟我的其他文章也講解的比較有趣😁,如果喜歡博主的講解方式,可以多多支持一下,感謝🤗!
🌟了解組合模式請(qǐng)看: (十 一)趣學(xué)設(shè)計(jì)模式 之 組合模式!
?更多請(qǐng)看個(gè)人主頁(yè): 碼熔burning
這篇文章帶你詳細(xì)認(rèn)識(shí)一下設(shè)計(jì)模式中的享元模式
一、 啥是享元模式?
想象一下,你正在玩一個(gè)大型的在線游戲 🎮。 游戲中有成千上萬(wàn)的士兵 💂,每個(gè)士兵都有自己的位置、生命值、裝備等等。 如果為每個(gè)士兵都創(chuàng)建一個(gè)完整的對(duì)象,會(huì)消耗大量的內(nèi)存 🧠。 但是,很多士兵的外觀、屬性都是相同的,只有位置不同。
享元模式,就是運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象! 享元模式通過(guò)共享盡可能多的對(duì)象來(lái)最小化內(nèi)存使用 💾。
簡(jiǎn)單來(lái)說(shuō),就是把對(duì)象的狀態(tài)分成內(nèi)部狀態(tài)和外部狀態(tài),共享內(nèi)部狀態(tài),減少對(duì)象數(shù)量! ??
- 你的程序需要?jiǎng)?chuàng)建大量的相似對(duì)象: 就像游戲中的士兵 🎮💂!
- 對(duì)象的很多狀態(tài)都可以共享: 就像士兵的外觀、屬性 🎮!
- 你想減少內(nèi)存消耗: 就像你想讓游戲運(yùn)行更流暢 🧠!
二、 為什么要用享元模式?
用享元模式,好處多多 👍:
- 減少內(nèi)存消耗: 通過(guò)共享對(duì)象,減少內(nèi)存占用 💾!
- 提高性能: 減少對(duì)象創(chuàng)建和銷毀的開(kāi)銷 🚀!
- 提高系統(tǒng)擴(kuò)展性: 可以支持更多的對(duì)象 ?!
三、 享元模式的實(shí)現(xiàn)方式
享元模式主要包含以下幾個(gè)角色:
- Flyweight(享元): 定義享元對(duì)象的接口,聲明可以被共享的內(nèi)部狀態(tài),并提供接受外部狀態(tài)的方法。 🎮💂 (比如:士兵的基類)
- ConcreteFlyweight(具體享元): 實(shí)現(xiàn)享元接口,存儲(chǔ)內(nèi)部狀態(tài)。 🎮💂 (比如:具體的士兵對(duì)象)
- UnsharedConcreteFlyweight(非共享具體享元): 不是共享的享元對(duì)象,通常包含一些不能被共享的狀態(tài)。 (比如:擁有特殊裝備的士兵)
- FlyweightFactory(享元工廠): 創(chuàng)建和管理享元對(duì)象,確保享元對(duì)象可以被共享。 🏭 (比如:士兵工廠)
- Client(客戶端): 使用享元對(duì)象,并提供外部狀態(tài)。 🎮 (比如:游戲客戶端)
內(nèi)部狀態(tài): 指的是對(duì)象可以共享的狀態(tài),存儲(chǔ)在享元對(duì)象內(nèi)部,不會(huì)隨著環(huán)境改變而改變。 (比如:士兵的外觀、屬性)
外部狀態(tài): 指的是對(duì)象不能共享的狀態(tài),需要由客戶端提供,會(huì)隨著環(huán)境改變而改變。 (比如:士兵的位置、生命值)
代碼示例:
import java.util.HashMap;
import java.util.Map;// 享元:士兵接口
public interface Soldier {void display(int x, int y); // 顯示士兵
}// 具體享元:士兵
public class ConcreteSoldier implements Soldier {private String model; // 士兵模型public ConcreteSoldier(String model) {this.model = model;}@Overridepublic void display(int x, int y) {System.out.println("士兵模型:" + model + ",位置:(" + x + ", " + y + ")");}
}// 享元工廠:士兵工廠
public class SoldierFactory {private static Map<String, Soldier> soldierMap = new HashMap<>(); // 存儲(chǔ)士兵對(duì)象public static Soldier getSoldier(String model) {Soldier soldier = soldierMap.get(model);if (soldier == null) {soldier = new ConcreteSoldier(model);soldierMap.put(model, soldier);}return soldier;}
}// 客戶端
public class Client {public static void main(String[] args) {Soldier soldier1 = SoldierFactory.getSoldier("步兵"); // 獲取步兵soldier1.display(10, 20); // 顯示步兵Soldier soldier2 = SoldierFactory.getSoldier("步兵"); // 獲取步兵soldier2.display(30, 40); // 顯示步兵Soldier soldier3 = SoldierFactory.getSoldier("騎兵"); // 獲取騎兵soldier3.display(50, 60); // 顯示騎兵System.out.println("士兵數(shù)量:" + SoldierFactory.soldierMap.size()); // 輸出士兵數(shù)量}
}
分析:
Soldier
是享元接口,定義了士兵的顯示方法。ConcreteSoldier
是具體享元,實(shí)現(xiàn)了士兵接口,存儲(chǔ)了士兵的模型。SoldierFactory
是享元工廠,創(chuàng)建和管理士兵對(duì)象,確保相同模型的士兵對(duì)象只創(chuàng)建一個(gè)。
輸出結(jié)果:
士兵模型:步兵,位置:(10, 20)
士兵模型:步兵,位置:(30, 40)
士兵模型:騎兵,位置:(50, 60)
士兵數(shù)量:2
可以看到,雖然創(chuàng)建了三個(gè)士兵對(duì)象,但是實(shí)際只創(chuàng)建了兩個(gè)士兵對(duì)象,因?yàn)椴奖鴮?duì)象被共享了。
四、 享元模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 減少內(nèi)存消耗 💾!
- 提高性能 🚀!
- 提高系統(tǒng)擴(kuò)展性 ?!
缺點(diǎn):
- 增加了系統(tǒng)的復(fù)雜度 😫!
- 需要分離內(nèi)部狀態(tài)和外部狀態(tài),設(shè)計(jì)難度較高 🧠!
- 共享對(duì)象的狀態(tài)不可修改,否則會(huì)影響其他使用該對(duì)象的客戶端 🔒!
五、 享元模式的應(yīng)用場(chǎng)景
- 當(dāng)你的程序需要?jiǎng)?chuàng)建大量的相似對(duì)象時(shí): 就像游戲中的士兵 🎮💂!
- 對(duì)象的很多狀態(tài)都可以共享: 就像士兵的外觀、屬性 🎮!
- 你想減少內(nèi)存消耗: 就像你想讓游戲運(yùn)行更流暢 🧠!
- 文本編輯器: 文本編輯器可以使用享元模式來(lái)共享字符對(duì)象,減少內(nèi)存消耗。
- 數(shù)據(jù)庫(kù)連接池: 數(shù)據(jù)庫(kù)連接池可以使用享元模式來(lái)共享數(shù)據(jù)庫(kù)連接對(duì)象,提高性能。
六、 總結(jié)
- 享元模式就像把對(duì)象的狀態(tài)分成內(nèi)部狀態(tài)和外部狀態(tài),共享內(nèi)部狀態(tài),減少對(duì)象數(shù)量! ??
- 主要包含享元、具體享元、非共享具體享元和享元工廠四個(gè)角色! 🎭
- 優(yōu)點(diǎn)是減少內(nèi)存消耗、提高性能、提高系統(tǒng)擴(kuò)展性! 👍
- 缺點(diǎn)是增加復(fù)雜度、設(shè)計(jì)難度較高、共享對(duì)象的狀態(tài)不可修改! 👎
- 適用于需要?jiǎng)?chuàng)建大量的相似對(duì)象,且對(duì)象的很多狀態(tài)都可以共享的場(chǎng)景! 🎯
希望這篇文章能讓你徹底理解享元模式! 💯 祝你學(xué)習(xí)愉快! 😄
看完請(qǐng)看:(十 三)趣學(xué)設(shè)計(jì)模式 之 模版方法模式!