簡介姓名 :享元模式 英文名 :Flyweight Pattern 價(jià)值觀 :共享富貴 個(gè)人介紹 : 你要的故事還記得筆袋么?可能有人已經(jīng)忘記了,在寫這篇文章之前其實(shí)我也忘了,從初中開始就再也沒用過筆袋。拿筆袋來講享元模式再適合不過了。筆袋放各種各樣的筆,今天我們不講別的,就講蠟筆。前段時(shí)間在逛公園的時(shí)候,看到一位老師在畫畫,畫的就是蠟筆畫,第一次看到真正的蠟筆畫,真的很震撼,原來蠟筆也可以把景色畫得那么美。當(dāng)時(shí)偷偷拍了一張,看下圖。 我們就拿這幅畫來說,里面畫了草、樹、路、山、天空等等。如果沒有用享元模式,我們可能這樣子實(shí)現(xiàn)。 蠟筆接口。 interface ICrayon { void draw(String place); } 蠟筆。 /** * 蠟筆 */ class Crayon implements ICrayon { private String color; public Crayon(String color) { System.out.println("---新建【" + color + "】蠟筆" ); this.color = color; } @Override public void draw(String place) { System.out.println("用" + this.color + "蠟筆畫" + place); } } 測試代碼。這幅畫是小明和小紅一起畫,小明畫了草和路,小紅畫了樹和藍(lán)天。 public class NoFlyweightTest { public static void main(String[] args) { drawByXiaoMing(); drawByXiaoHong(); } public static void drawByXiaoMing() { ICrayon greenCrayon = new Crayon("綠色"); greenCrayon.draw("草"); ICrayon grayCrayon = new Crayon("灰色"); grayCrayon.draw("路"); } public static void drawByXiaoHong() { ICrayon blueCrayon = new Crayon("藍(lán)色"); blueCrayon.draw("藍(lán)天"); ICrayon greenCrayon = new Crayon("綠色"); greenCrayon.draw("樹"); } } 打印結(jié)果: ---新建【綠色】蠟筆 用綠色蠟筆畫草 ---新建【灰色】蠟筆 用灰色蠟筆畫路 ---新建【藍(lán)色】蠟筆 用藍(lán)色蠟筆畫藍(lán)天 ---新建【綠色】蠟筆 用綠色蠟筆畫樹 我們發(fā)現(xiàn)小明和小紅都用了綠色蠟筆,而這里新建了 2 次綠色蠟筆,也就是在整個(gè)作畫過程中,小明和小紅并不是共用一套蠟筆,而是各自用一套蠟筆,在現(xiàn)實(shí)中是沒什么問題的,但是在軟件開發(fā)中,如果這種情況出現(xiàn),其實(shí)相當(dāng)于資源浪費(fèi),因?yàn)槊總€(gè)蠟筆都會(huì)占用內(nèi)存,可以共用的我們盡量共用,節(jié)省一些內(nèi)存空間,特別是出現(xiàn)很多這種可以共享卻沒有共享的對(duì)象時(shí)候。下面我們引入享元模式。享元模式實(shí)現(xiàn)方法相當(dāng)于我們蠟筆都放在了筆袋,小明和小紅用完就放到筆袋里面,每一種顏色的蠟筆只有一根,也就是他們共用一套蠟筆。代碼如下所示。 筆袋代碼。我們用了 Map 作為容器,如果容器里面沒有想要顏色的蠟筆,則創(chuàng)建新的蠟筆,并存到容器里。 /** * 筆袋 */ class CrayonFactory { private static Map<String, ICrayon> data = new HashMap<>(); public static ICrayon getCrayon(String color) { if (data.containsKey(color)) { return data.get(color); } ICrayon crayon = new Crayon(color); data.put(color, crayon); return crayon; } } 測試代碼。 public class FlyweightTest { public static void main(String[] args) { drawByXiaoMing(); drawByXiaoHong(); } public static void drawByXiaoMing() { ICrayon greenCrayon = CrayonFactory.getCrayon("綠色"); greenCrayon.draw("草"); ICrayon grayCrayon = CrayonFactory.getCrayon("灰色"); grayCrayon.draw("路"); } public static void drawByXiaoHong() { ICrayon blueCrayon = CrayonFactory.getCrayon("藍(lán)色"); blueCrayon.draw("藍(lán)天"); ICrayon greenCrayon = CrayonFactory.getCrayon("綠色"); greenCrayon.draw("樹"); } } 打印結(jié)果: ---新建【綠色】蠟筆 用綠色蠟筆畫草 ---新建【灰色】蠟筆 用灰色蠟筆畫路 ---新建【藍(lán)色】蠟筆 用藍(lán)色蠟筆畫藍(lán)天 用綠色蠟筆畫樹 利用享元模式實(shí)現(xiàn)的結(jié)果,小紅畫樹所用到的綠色蠟筆跟小明畫草的綠色蠟筆一樣,小紅用到時(shí)并沒有新建綠色蠟筆。 總結(jié)是不是有一種,原來這就是享元模式的感覺?平時(shí)開發(fā)過程中經(jīng)常見到這種因?yàn)楹芏嘀貜?fù)的對(duì)象,所以利用享元模式來實(shí)現(xiàn)的場景。享元模式合理提高了對(duì)象的復(fù)用性,減少了程序的內(nèi)存占用,還有一個(gè)提高性能的地方就是減少了對(duì)象創(chuàng)建的過程。好了,收下這個(gè)簡單的設(shè)計(jì)模式。歡迎關(guān)注公眾號(hào),一起學(xué)習(xí)進(jìn)步。 |
|