【設計模式】(十七)–結構型模式–享元模式
享元模式定義
Use sharing to support large numbers of fine-grained objects efficiently.
意思是:使用共享對象可以有效地支持大量的細粒度的對象。
享元模式是池技術的重要實現,可以降低大量重複的、細粒度的類在內存中的開銷。享元模式與對象池模式(創建者模式)有一定區別,對象池模式是保持可變域對象的容器,而享元模式是不可變域對象。
享元對象能做到共享的關鍵是能夠區分內部狀態和外部狀態。
- 內部狀態 存儲在享元對象內部的、可以共享的信息。不會隨環境改變而改變
- 外部狀態 隨環境變化而改變的不可以共享的狀態。享元對象的外部狀態必須由外部客戶端保存,並且被創建後在需要時需要在傳入享元對象內部。
享元模式通常有5個元素
- Client 客戶端代碼
- FlyweightFactory 享元工廠類,如果享元對象不存在則創建,否則則返回
- Flyweight 抽象享元類
- ConcreateShareableFlyweight 與其同伴共享狀態的享元對象
- ConcreateUnShareableFlyweight 不共享其狀態的享元對象。它可以由多個具體的享元對象組成。
Java基礎類庫中大量使用了享元模式,如String、Integer、Boolean、Character等類都通過享元模式提供了內部的池化機制。
享元模式的優點
享元模式大大減少對象的創建,降低系統的內存,使效率提高。
但是享元模式提高了系統的複雜度,需要分離出外部狀態和內部狀態,而且外部狀態具有固有化的性質,不應該隨着內部狀態的變化而變化,否則會造成系統的混亂。
享元模式的使用場景
- 1、系統有大量相似對象。
- 2、需要緩衝池的場景。
享元模式的簡單實現
類圖
實現
public class Test {
public static void main(String[] args) {
System.out.println("開一局手機遊戲");
Hero arthur = FlyweightFactory.getHero("Arthur");
arthur.move("上路");
Hero angela = FlyweightFactory.getHero("Angela");
angela.move("中路");
}
}
/**
* 英雄
*/
public interface Hero {
void move(String line);
}
public class HeroFlyweight implements Hero {
/**
* 英雄姓名
*/
private String name;
/**
* 英雄裝扮
*/
private String clothing;
@Override
public void move(String line) {
System.out.println(clothing + name + "移動到" + line);
}
public HeroFlyweight(String name, String clothing) {
this.name = name;
this.clothing = clothing;
}
}
public class FlyweightFactory {
private static final Hero Arthur = new HeroFlyweight("亞瑟", "無裝扮");
private static final Hero Angela = new HeroFlyweight("安琪拉", "無裝扮");
public static Hero getHero(String name) {
if ("Arthur".equals(name)) {
return Arthur;
} else if ("Angela".equals(name)) {
return Angela;
}
return null;
}
}
結果
實現解讀,這樣英雄池建立好,用戶只要選擇對應池中的英雄即可。