Java設(shè)計(jì)模式之享元模式示例詳解
定義
享元模式(FlyWeight Pattern),也叫蠅量模式,運(yùn)用共享技術(shù),有效的支持大量細(xì)粒度的對(duì)象,享元模式就是池技術(shù)的重要實(shí)現(xiàn)方式。
原理類圖
- Flyweight :抽象的享元角色,他是抽象的產(chǎn)品類,同時(shí)他會(huì)定義出對(duì)象的內(nèi)部狀態(tài)和外部狀態(tài)
- ConcreteFlyweight :是具體的享元角色,具體的產(chǎn)品類,實(shí)現(xiàn)抽象角色,實(shí)現(xiàn)具體的業(yè)務(wù)邏輯
- UnsharedConcreteFlyweight :不可共享的角色,這個(gè)角色也可能出現(xiàn)在享元模式中
- FlyweightFactory :享元工廠類,用于構(gòu)建一個(gè)池的容器,同時(shí)在享元工廠里會(huì)提供公共方法 (從池子里獲取對(duì)象,獲取池子里的對(duì)象總數(shù),根據(jù)key獲取對(duì)象,,)
- Client:客戶端了,使用享元模式去完成業(yè)務(wù)邏輯
案例
需求
我們接了一個(gè)小型的外包項(xiàng)目,給客戶老王做一個(gè)產(chǎn)品展示網(wǎng)頁(yè),老王的朋友們感覺(jué)效果不錯(cuò),也希望做這樣的產(chǎn)品展示網(wǎng)頁(yè),但是他們要求都有些不同
1)有客戶要求網(wǎng)頁(yè)以新聞的形式發(fā)布
2)有客戶要求網(wǎng)頁(yè)以博客的形式發(fā)布
3)有客戶希望網(wǎng)頁(yè)以微信公眾號(hào)的形式發(fā)布
方案:享元模式
定義網(wǎng)站用戶類
public class User { private String name; public User(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
定義網(wǎng)站抽象類——享元角色
public abstract class Website { public abstract void show(User user); }
定義具體的網(wǎng)站類——具體的享元角色
public class ConcreteWebsite extends Website{ // 網(wǎng)站的發(fā)布形式 private String type; public ConcreteWebsite(String type){ this.type = type; } @Override public void show(User user) { System.out.println("以" + type + "形式發(fā)布網(wǎng)站"); System.out.println("網(wǎng)站的用戶名是:" + user.getName()); } }
定義網(wǎng)站工廠類——享元工廠類
public class WebsiteFactory { // 創(chuàng)建HashMap,充當(dāng)池的角色 private HashMap<String, ConcreteWebsite> pool = new HashMap<String, ConcreteWebsite>(); // 根據(jù)類型判斷,獲取池子里的對(duì)象 public Website getWebsite(String type){ if(!pool.containsKey(type)){ pool.put(type,new ConcreteWebsite(type)); } return pool.get(type); } // 獲取池子里的對(duì)象總數(shù) public int getWebsiteCount(){ System.out.println("當(dāng)前池子里的對(duì)象總數(shù):" + pool.size()); return pool.size(); } }
定義客戶端測(cè)試類
public class Client { public static void main(String[] args) { //創(chuàng)建一個(gè)享元工廠 WebsiteFactory websiteFactory = new WebsiteFactory(); Website news = websiteFactory.getWebsite("新聞"); news.show(new User("老李")); Website wechat = websiteFactory.getWebsite("博客"); wechat.show(new User("老高")); websiteFactory.getWebsiteCount(); Website wechat1 = websiteFactory.getWebsite("微信"); wechat.show(new User("老沈")); websiteFactory.getWebsiteCount(); } }
查看測(cè)試結(jié)果
分析
通過(guò)一個(gè)工廠類來(lái)根據(jù)不同類型的需求,從而生成對(duì)應(yīng)的具體的享元對(duì)象,實(shí)現(xiàn)了需求。其中享元對(duì)象的信息分為兩個(gè)部分,內(nèi)部狀態(tài)和外部狀態(tài)。內(nèi)部對(duì)象是指對(duì)象共享出來(lái)的信息,存儲(chǔ)在享元對(duì)象內(nèi)部,不隨著環(huán)境的改變而改變,外部對(duì)象隨著環(huán)境的改變而改變,不可共享的狀態(tài)。
總結(jié)
優(yōu)勢(shì)
節(jié)省內(nèi)存空間,重復(fù)對(duì)象需要被頻繁創(chuàng)建的時(shí)候,享元模式由于只會(huì)被創(chuàng)建一次,所以對(duì)系統(tǒng)的內(nèi)存空間的需求大大減小
提高使用效率,對(duì)于可重復(fù)的對(duì)象只創(chuàng)建一次,再次訪問(wèn)時(shí)直接從池子里拿,相應(yīng)速度更快,效率也會(huì)更高局限性享元模式會(huì)提高
劣勢(shì)
享元模式會(huì)提高系統(tǒng)的復(fù)雜度,享元模式需要有一個(gè)工廠類加以控制,如果盲目使用,會(huì)提高系統(tǒng)邏輯的復(fù)雜度
使用場(chǎng)景
享元模式最經(jīng)典的使用場(chǎng)景就是我們各類池技術(shù)了
系統(tǒng)中有大量對(duì)象的時(shí)候,這些對(duì)象消耗大量?jī)?nèi)存,可以考慮使用享元模式
到此這篇關(guān)于Java設(shè)計(jì)模式之享元模式示例詳解的文章就介紹到這了,更多相關(guān)Java享元模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 實(shí)現(xiàn)repalceAll只替換第二個(gè)匹配到的字符串
這篇文章主要介紹了Java 實(shí)現(xiàn)repalceAll只替換第二個(gè)匹配到的字符串,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12Java實(shí)現(xiàn)的決策樹算法完整實(shí)例
這篇文章主要介紹了Java實(shí)現(xiàn)的決策樹算法,簡(jiǎn)單描述了決策樹的概念、原理,并結(jié)合完整實(shí)例形式分析了java實(shí)現(xiàn)決策樹算法的相關(guān)操作技巧,代碼中備有較為詳盡的注釋便于理解,需要的朋友可以參考下2017-11-11Java lambda表達(dá)式實(shí)現(xiàn)Flink WordCount過(guò)程解析
這篇文章主要介紹了Java lambda表達(dá)式實(shí)現(xiàn)Flink WordCount過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02mybatis自動(dòng)填充時(shí)間字段示例代碼
這篇文章主要給大家介紹了關(guān)于mybatis自動(dòng)填充時(shí)間字段的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01Mybatis中TypeAliasRegistry的作用及使用方法
Mybatis中的TypeAliasRegistry是一個(gè)類型別名注冊(cè)表,它的作用是為Java類型建立別名,使得在Mybatis配置文件中可以使用別名來(lái)代替完整的Java類型名。使用TypeAliasRegistry可以簡(jiǎn)化Mybatis配置文件的編寫,提高配置文件的可讀性和可維護(hù)性2023-05-05JNI實(shí)現(xiàn)最簡(jiǎn)單的JAVA調(diào)用C/C++代碼
這篇文章主要介紹了JNI實(shí)現(xiàn)最簡(jiǎn)單的JAVA調(diào)用C/C++代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08