享元模式
一、定義
使用共享對象可有效的支持大量的細粒度的對象
要求細粒度對象,就會使得對象數量多而且性質相近,爲了區分,將對象分爲兩個部分:內部狀態與外部狀態
內部狀態,內部狀態是對象可共享出來的信息,存儲在享元對象內部並且不會隨着環境改變而改變,他們可以作爲一個對象的動態附加信息,不必直接存儲在具體某個對象中,屬於可共享的部分
外部狀態,外部狀態是對象得以依賴的一個標記,是對環境改變而改變的、不可共享的部分,是一批對對象的統一標識
享元模式的通用類圖
Flyweight是抽象享元角色,是一個產品的抽象類,同時定義出對象的外部狀態和內部轉檯的接口或實現;ConcertedFlyweight是具體享元角色,是具體的產品類,該角色的內部轉檯處理應該是與環境無關,不能出現一個操作改變了內部轉檯,同時修改了外部狀態;unsharedConcreteFlyweight是不可共享的享元角色,不存在外部狀態或者安全要求(如,線程安全)不能夠使用共享技術的對象,該對象一般不出現在享元工廠中;FlyweightFactory是享元工廠,負責構造一個池容器,同時提供從池中獲得對象的方法。
享元模式通用源碼
-
抽象享元角色
public abstract class Flyweight { //內部狀態 private String intrinsic; //外部狀態 protected final String Extrinsic; //要求享元角色必須接受外部狀態 public Flyweight(String _Extrinsic){ this.Extrinsic = _Extrinsic; } //定義業務操作 public abstract void operate(); //內部狀態的getter/setter public String getIntrinsic() { return intrinsic; } public void setIntrinsic(String intrinsic) { this.intrinsic = intrinsic; } }
-
具體享元角色
public class ConcreteFlyweight1 extends Flyweight{ //接受外部狀態 public ConcreteFlyweight1(String _Extrinsic){ super(_Extrinsic); } //根據外部狀態進行邏輯處理 public void operate(){ //業務邏輯 } }
public class ConcreteFlyweight2 extends Flyweight{ //接受外部狀態 public ConcreteFlyweight2(String _Extrinsic){ super(_Extrinsic); } //根據外部狀態進行邏輯處理 public void operate(){ //業務邏輯 } }
-
享元工廠
public class FlyweightFactory { //定義一個池容器 private static HashMap<String,Flyweight> pool= new HashMap<String,Flyweight>(); //享元工廠 public static Flyweight getFlyweight(String Extrinsic){ //需要返回的對象 Flyweight flyweight = null; //在池中沒有該對象 if(pool.containsKey(Extrinsic)){ flyweight = pool.get(Extrinsic); }else{ //根據外部狀態創建享元對象 flyweight = new ConcreteFlyweight1(Extrinsic); //放置到池中 pool.put(Extrinsic, flyweight); } return flyweight; } }
二、享元模式的優點
- 減少對象的創建、降低程序內存佔用,增強程序的性能
三、享元模式的缺點
- 提高了系統複雜性,需要分離外部狀態和內部狀態
四、享元模式的使用場景
- 系統中存在大量的相似對象
- 細粒度的對象都具備較接近的外部狀態,而且內部狀態與環境無關,也就是說對象沒有特定身份
- 需要緩衝池的場景