類圖
定義
使用共享對象可有效地支持大量的細粒度的對象
優點
- 大大減少應用程序創建的對象,降低程序內存的佔用,增強程序的性能缺點
- 提高了系統的複雜性,需要分離出外部狀態和內部狀態
使用場景
- 系統中存在大量相似對象
- 細粒度的對象都具備較接近的外部狀態,且內部狀態與環境無關
- 需要緩衝池的場景
注意事項
外部狀態最好以java基本類型(int,string等)作爲標誌,可以大幅提高效率。
如果把一個對象作爲鍵值,一定要確保重寫了equals和hashcode方法。
關於對象池和享元模式的區別,對象池着重在對象的複用上,池中的每個對象是可替換的,
從同一個池中獲得A對象和B對象對客戶端來說是完全相同的,它主要解決服用,
而享元模式主要解決的是對象的共享問題,如何建立多個可共享的細粒度對象則是其關注的重點
抽象享元角色
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 ConcreteFlyWeight extends FlyWeight {
/**
* @param _extrinsic
*/
public ConcreteFlyWeight(String _extrinsic) {
super(_extrinsic);
}
/**
* 根據外部狀態進行邏輯處理
*/
@Override
public void operate() {
System.out.println("ConcreteFlyWeight->" + extrinsic);
System.out.println("ConcreteFlyWeight->" + getIntrinsic());
}
}
享元工廠
public class FlyWeightFactory {
private static HashMap<String, FlyWeight> pool = new HashMap<>();
public static FlyWeight getFlyWeight(String extrinsic) {
FlyWeight flyWeight;
if (pool.containsKey(extrinsic)) {
flyWeight = pool.get(extrinsic);
} else {
flyWeight = new ConcreteFlyWeight(extrinsic);
pool.put(extrinsic, flyWeight);
}
return flyWeight;
}
}
場景類
public class Client {
public static void main(String[] args) {
// fw1和fw2共享了同一個對象
FlyWeight fw1 = FlyWeightFactory.getFlyWeight("name 1");
fw1.setIntrinsic("fw1");
fw1.operate();
FlyWeight fw2 = FlyWeightFactory.getFlyWeight("name 1");
fw2.setIntrinsic("fw2");
fw2.operate();
// fw3使用了一個新對象
FlyWeight fw3 = FlyWeightFactory.getFlyWeight("name 3");
fw3.setIntrinsic("fw3");
fw3.operate();
}
}
運行結果
ConcreteFlyWeight->name 1
ConcreteFlyWeight->fw1
ConcreteFlyWeight->name 1
ConcreteFlyWeight->fw2
ConcreteFlyWeight->name 3
ConcreteFlyWeight->fw3