Java設(shè)計(jì)模式之享元模式(Flyweight Pattern)詳解
享元模式概念
享元模式(Flyweight Pattern)是一種結(jié)構(gòu)型設(shè)計(jì)模式,旨在減少對(duì)象的數(shù)量,以節(jié)省內(nèi)存空間和提高性能。它通過(guò)共享相同或相似狀態(tài)的多個(gè)對(duì)象來(lái)減少對(duì)象的數(shù)量。享元模式通常用于大量創(chuàng)建細(xì)粒度對(duì)象的場(chǎng)景。
享元模式使用場(chǎng)景
在享元模式中,我們創(chuàng)建一個(gè)工廠類(Flyweight Factory),該工廠類對(duì)外提供獲取享元對(duì)象的方法。享元對(duì)象包含兩部分屬性:內(nèi)部狀態(tài)(Intrinsic State)和外部狀態(tài)(Extrinsic State)。內(nèi)部狀態(tài)指不隨外界環(huán)境改變而改變的共享部分,外部狀態(tài)指隨著環(huán)境的改變而改變的部分。
當(dāng)客戶端需要一個(gè)享元對(duì)象時(shí),它向工廠類請(qǐng)求一個(gè)對(duì)象,工廠類會(huì)首先查詢對(duì)象池中是否已經(jīng)有該對(duì)象的實(shí)例。如果有,就直接返回對(duì)象池中的實(shí)例;如果沒(méi)有,則創(chuàng)建一個(gè)新的實(shí)例并將其放入對(duì)象池中,同時(shí)返回給客戶端。
享元模式優(yōu)缺點(diǎn)
享元模式的優(yōu)點(diǎn)在于,它可以大大減少系統(tǒng)中對(duì)象的數(shù)量,從而提高系統(tǒng)的性能和內(nèi)存利用率。它也可以使得代碼更加簡(jiǎn)潔,易于維護(hù)和擴(kuò)展。
但是,享元模式也有一些缺點(diǎn),在某些情況下,它可能會(huì)犧牲部分內(nèi)存以換取性能的提升。同時(shí),由于享元對(duì)象通常是不可變的對(duì)象,因此可能會(huì)對(duì)系統(tǒng)中的某些業(yè)務(wù)邏輯造成影響。
享元模式代碼案例
下面以一個(gè)具體例子,比如制作黑白棋游戲來(lái)進(jìn)一步說(shuō)明:
對(duì)于黑白棋這個(gè)游戲來(lái)說(shuō),我們需要大量的棋子對(duì)象,如果為每一個(gè)棋子都單獨(dú)創(chuàng)建一個(gè)對(duì)象,那么系統(tǒng)的性能和內(nèi)存開(kāi)銷都會(huì)非常大。而使用享元模式,我們可以將一些相同的棋子對(duì)象共享起來(lái),只需要保存其內(nèi)部和外部狀態(tài)區(qū)分即可。例如,黑方和白方用不同顏色的棋子,但同一顏色的棋子之間是可以互相替換的。
定義棋子類Piece
public interface Piece { void put(int x, int y); } public class BlackPiece implements Piece { @Override public void put(int x, int y) { System.out.println("在坐標(biāo) (" + x + ", " + y + ") 放置了一個(gè)黑棋子"); } } public class WhitePiece implements Piece { @Override public void put(int x, int y) { System.out.println("在坐標(biāo) (" + x + ", " + y + ") 放置了一個(gè)白棋子"); } }
以上代碼實(shí)現(xiàn)了兩個(gè)具體的棋子類:BlackPiece 和 WhitePiece。它們都實(shí)現(xiàn)了 Piece 接口,并重寫了其中的 put() 方法,用于在指定坐標(biāo)放棋子。
實(shí)現(xiàn)享元工廠類PieceFactory
import java.util.HashMap; import java.util.Map; public class PieceFactory { private final Map<String, Piece> map = new HashMap<>(); public Piece getPiece(String color) { Piece piece = map.get(color); if (piece == null) { switch (color) { case "black": piece = new BlackPiece(); break; case "white": piece = new WhitePiece(); break; default: throw new IllegalArgumentException("Unsupported color: " + color); } map.put(color, piece); } return piece; } }
以上代碼實(shí)現(xiàn)了一個(gè)操作棋子對(duì)象的共享工廠PieceFactory,其中使用了HashMap來(lái)保存已經(jīng)創(chuàng)建過(guò)的棋子對(duì)象。直接調(diào)用getPiece()方法即可根據(jù)顏色獲取相應(yīng)的棋子對(duì)象。如果該顏色的棋子對(duì)象不存在,則創(chuàng)建一個(gè)新的棋子對(duì)象并存入map中,否則直接從map中獲取棋子對(duì)象。
在客戶端中使用享元模式
public class Client { public static void main(String[] args) { PieceFactory factory = new PieceFactory(); Piece black1 = factory.getPiece("black"); black1.put(1, 1); Piece black2 = factory.getPiece("black"); black2.put(2, 2); Piece white1 = factory.getPiece("white"); white1.put(3, 3); Piece white2 = factory.getPiece("white"); white2.put(4, 4); } }
在上面的代碼中,我們可以看到一個(gè)完整的享元模式實(shí)現(xiàn)。在客戶端中,我們只需要獲取工廠類中提供的共享對(duì)象即可,通過(guò)調(diào)用 put() 方法來(lái)為棋子設(shè)置坐標(biāo)。
通過(guò)以上例子,我們可以看出享元模式的優(yōu)點(diǎn):它大幅度減少內(nèi)存占用并提高了系統(tǒng)性能,對(duì)于類似的大量重復(fù)對(duì)象的場(chǎng)景非常友好。
到此這篇關(guān)于Java設(shè)計(jì)模式之享元模式(Flyweight Pattern)詳解的文章就介紹到這了,更多相關(guān)Java 享元模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用SpringSecurity+defaultSuccessUrl不跳轉(zhuǎn)指定頁(yè)面的問(wèn)題解決方法
本人是用springsecurity的新手,今天遇到defaultSuccessUrl不跳轉(zhuǎn)指定頁(yè)面的問(wèn)題,真是頭疼死了,網(wǎng)上找遍了解決方法都解決不了,今天給大家分享使用SpringSecurity+defaultSuccessUrl不跳轉(zhuǎn)指定頁(yè)面的問(wèn)題解決方法,感興趣的朋友一起看看吧2023-12-12從Myeclipse 導(dǎo)入到eclipse中無(wú)法識(shí)別為 web項(xiàng)目 問(wèn)題的解決步驟
這篇文章主要介紹了從Myeclipse 導(dǎo)入到eclipse中無(wú)法識(shí)別為 web項(xiàng)目 問(wèn)題的解決步驟,需要的朋友可以參考下2018-05-05SpringBoot+Jersey跨域文件上傳的實(shí)現(xiàn)示例
在SpringBoot開(kāi)發(fā)后端服務(wù)時(shí),我們一般是提供接口給前端使用,本文主要介紹了SpringBoot+Jersey跨域文件上傳的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07詳解MyBatisPlus邏輯刪除與唯一索引沖突問(wèn)題
這篇文章主要介紹了詳解MyBatisPlus邏輯刪除與唯一索引沖突問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03win7 64位系統(tǒng)JDK安裝配置環(huán)境變量教程
這篇文章主要為大家詳細(xì)介紹了win7 64位系統(tǒng)JDK安裝配置環(huán)境變量教程,感興趣的小伙伴們可以參考一下2016-06-06SpringBoot快速接入DeepSeek?api(帶頁(yè)面)保姆級(jí)教程
這篇文章主要介紹了如何在Java端接入DeepSeek?API,包括申請(qǐng)APIkey、項(xiàng)目結(jié)構(gòu)展示、編寫controller和前端界面、以及測(cè)試啟動(dòng)項(xiàng)目的過(guò)程,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-03-03