文章首發(fā):
結(jié)構(gòu)型模式:享元模式
七大結(jié)構(gòu)型模式之六:享元模式奈梳。
簡(jiǎn)介
姓名 :享元模式
英文名 :Flyweight Pattern
價(jià)值觀 :共享富貴
個(gè)人介紹 :
Use sharing to support large numbers of fine-grained objects efficiently.
使用共享對(duì)象可有效地支持大量的細(xì)粒度的對(duì)象飞涂。
(來自《設(shè)計(jì)模式之禪》)
你要的故事
還記得筆袋么志珍?可能有人已經(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);
}
}
測(cè)試代碼晶默。這幅畫是小明和小紅一起畫,小明畫了草和路航攒,小紅畫了樹和藍(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;
}
}
測(cè)試代碼。
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)的場(chǎng)景假瞬。享元模式合理提高了對(duì)象的復(fù)用性陕靠,減少了程序的內(nèi)存占用迂尝,還有一個(gè)提高性能的地方就是減少了對(duì)象創(chuàng)建的過程。好了剪芥,收下這個(gè)簡(jiǎn)單的設(shè)計(jì)模式垄开。歡迎關(guān)注公眾號(hào),一起學(xué)習(xí)進(jìn)步税肪。
推薦閱讀
公眾號(hào)后臺(tái)回復(fù)『大禮包』獲取 Java溉躲、Python、IOS 等教程
加個(gè)人微信備注『教程』獲取架構(gòu)師益兄、機(jī)器學(xué)習(xí)等教程