文章首發: "結構型模式:享元模式" 七大結構型模式之六:享元模式。 簡介 姓名 :享元模式 英文名 :Flyweight Pattern 價值觀 :共用富貴 個人介紹 : Use sharing to support large numbers of fine grained objects ef ...
文章首發:
結構型模式:享元模式
七大結構型模式之六:享元模式。
簡介
姓名 :享元模式
英文名 :Flyweight Pattern
價值觀 :共用富貴
個人介紹 :
Use sharing to support large numbers of fine-grained objects efficiently.
使用共用對象可有效地支持大量的細粒度的對象。
(來自《設計模式之禪》)
你要的故事
還記得筆袋麽?可能有人已經忘記了,在寫這篇文章之前其實我也忘了,從初中開始就再也沒用過筆袋。拿筆袋來講享元模式再適合不過了。筆袋放各種各樣的筆,今天我們不講別的,就講蠟筆。前段時間在逛公園的時候,看到一位老師在畫畫,畫的就是蠟筆畫,第一次看到真正的蠟筆畫,真的很震撼,原來蠟筆也可以把景色畫得那麼美。當時偷偷拍了一張,看下圖。
我們就拿這幅畫來說,裡面畫了草、樹、路、山、天空等等。如果沒有用享元模式,我們可能這樣子實現。
蠟筆介面。
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);
}
}
測試代碼。這幅畫是小明和小紅一起畫,小明畫了草和路,小紅畫了樹和藍天。
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("藍色");
blueCrayon.draw("藍天");
ICrayon greenCrayon = new Crayon("綠色");
greenCrayon.draw("樹");
}
}
列印結果:
---新建【綠色】蠟筆
用綠色蠟筆畫草
---新建【灰色】蠟筆
用灰色蠟筆畫路
---新建【藍色】蠟筆
用藍色蠟筆畫藍天
---新建【綠色】蠟筆
用綠色蠟筆畫樹
我們發現小明和小紅都用了綠色蠟筆,而這裡新建了 2 次綠色蠟筆,也就是在整個作畫過程中,小明和小紅並不是共用一套蠟筆,而是各自用一套蠟筆,在現實中是沒什麼問題的,但是在軟體開發中,如果這種情況出現,其實相當於資源浪費,因為每個蠟筆都會占用記憶體,可以共用的我們儘量共用,節省一些記憶體空間,特別是出現很多這種可以共用卻沒有共用的對象時候。下麵我們引入享元模式。享元模式實現方法相當於我們蠟筆都放在了筆袋,小明和小紅用完就放到筆袋裡面,每一種顏色的蠟筆只有一根,也就是他們共用一套蠟筆。代碼如下所示。
筆袋代碼。我們用了 Map 作為容器,如果容器裡面沒有想要顏色的蠟筆,則創建新的蠟筆,並存到容器里。
/**
* 筆袋
*/
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("藍色");
blueCrayon.draw("藍天");
ICrayon greenCrayon = CrayonFactory.getCrayon("綠色");
greenCrayon.draw("樹");
}
}
列印結果:
---新建【綠色】蠟筆
用綠色蠟筆畫草
---新建【灰色】蠟筆
用灰色蠟筆畫路
---新建【藍色】蠟筆
用藍色蠟筆畫藍天
用綠色蠟筆畫樹
利用享元模式實現的結果,小紅畫樹所用到的綠色蠟筆跟小明畫草的綠色蠟筆一樣,小紅用到時並沒有新建綠色蠟筆。
總結
是不是有一種,原來這就是享元模式的感覺?平時開發過程中經常見到這種因為很多重覆的對象,所以利用享元模式來實現的場景。享元模式合理提高了對象的復用性,減少了程式的記憶體占用,還有一個提高性能的地方就是減少了對象創建的過程。好了,收下這個簡單的設計模式。歡迎關註公眾號,一起學習進步。
推薦閱讀
公眾號後臺回覆『大禮包』獲取 Java、Python、IOS 等教程
加個人微信備註『教程』獲取架構師、機器學習等教程