享元模式
共享內部狀態,加載外部狀態
內部狀態是不變的,外部狀態是可變的
分離變與不變是軟件設計上最基本的方式之一,比如預留接口:一個常見的原因就是這裏存在變化,因此預留接口作爲“可插入性的保證”。
優點
- 大幅度地降低內存中對象的數量,節省內存空間。
缺點
- 享元模式使得系統更加複雜。爲了使對象可以共享,需要將一些狀態外部化,這使得程序的邏輯複雜化。
- 享元模式將享元對象的狀態外部化,而讀取外部狀態使得運行時間變長。
本質
- 分離與共享
應用場景
- 一個系統有大量的對象
- 這些對象耗費大量的內存
- 這些對象的狀態中的大部分都可以外部化
- 這些對象可以按照內部狀態分成很多的組,當把外部.對象從對象中剔除時,每一個組都可以僅用一個對象代替
例如:
- 五子棋
- 圍棋
抽象接口類:
public abstract class FlyWeight {
public abstract void operation(int extrinsicState);
}
具體的享元類:
public class ConcreteFlyWeight extends FlyWeight {
@Override
public void operation(int extrinsicState) {
System.out.println("具體的FlyWeight "+extrinsicState);
}
}
不具體的享元類:
public class UnsharedFlyWeight extends FlyWeight {
@Override
public void operation(int extrinsicState) {
System.out.println("不具體的FlyWeight "+extrinsicState);
}
}
享元工廠類:
public class FlyWeightFactory {
private Hashtable<String, FlyWeight> hashtable = new Hashtable<String, FlyWeight>();
public FlyWeight getFlyWeight(String key) {
if (hashtable.containsKey(key)) {
return hashtable.get(key);
} else {
ConcreteFlyWeight concreteFlyWeight = new ConcreteFlyWeight();
hashtable.put(key, concreteFlyWeight);
return concreteFlyWeight;
}
}
public int getCount() {
return hashtable.size();
}
}
測試類:
public class Client {
public static void main(String[] args) {
int extrinsicstate = 10;
FlyWeightFactory factory = new FlyWeightFactory();
FlyWeight f1 = factory.getFlyWeight("X");
f1.operation(--extrinsicstate);
System.out.println(f1);
FlyWeight f2 = factory.getFlyWeight("Y");
f2.operation(--extrinsicstate);
FlyWeight f3 = factory.getFlyWeight("Z");
f3.operation(--extrinsicstate);
FlyWeight f4 = new UnsharedFlyWeight();
f4.operation(--extrinsicstate);
}
}