《Design Patterns》FlyWeight.積跬步系列

FlyWeight:享元模式

先代碼

package h.l.demo.flyweight;

import java.util.HashMap;

/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年3月8日
 * @Description: 它是所有具體享元類的超類或者接口,通過這個接口,FlyWeight可以接收並作用於外部狀態
 */
public abstract class FlyWeight {
	/**
	 * @param extrinsicState
	 *            外部狀態
	 */
	public abstract void operation(int extrinsicState);
}

/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年3月8日
 * @Description: 具體享元類
 */
class ConcreteFlyWeight extends FlyWeight {

	@Override
	public void operation(int extrinsicState) {
		System.out.println("具體FlyWeight:" + extrinsicState);
	}

}

/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年3月8日
 * @Description: 不共享的具體享元類
 */
class UnSharedConcreteFlyWeight extends FlyWeight {

	@Override
	public void operation(int extrinsicState) {
		System.out.println("不共享的具體FlyWeight:" + extrinsicState);
	}

}
/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年3月8日
 * @Description: 享元工廠:用來創建和管理FlyWeight對憲法,它主要作用時用來確保合理的共享FlyWeight
 */
class FlyWeightFactory {
	private HashMap<String, FlyWeight> map = new HashMap<>();

	public FlyWeightFactory(){
		map.put("X", new ConcreteFlyWeight());
		map.put("Y", new ConcreteFlyWeight());
		map.put("Z", new ConcreteFlyWeight());
	}
	public FlyWeight getFlyWeight(String key){
		if(map.get(key) == null){
			map.put(key, new ConcreteFlyWeight());
		}
		return map.get(key);
	}
}

測試類:

package h.l.demo.flyweight;
/**
 * 
 * @author: Is-Me-Hl
 * @date: 2020年1月31日
 * @Description: 測試
 */
public class TestMainEnter {

	public static void main(String[] args) {
		int extrinsicState = 1503;
		
		FlyWeightFactory f =new FlyWeightFactory();
		
		FlyWeight fx = f.getFlyWeight("X");
		fx.operation(--extrinsicState);
		
		FlyWeight fy = f.getFlyWeight("Y");
		fx.operation(--extrinsicState);
		
		FlyWeight fz = f.getFlyWeight("Z");
		fx.operation(--extrinsicState);
		
		FlyWeight uf = new UnSharedConcreteFlyWeight();
		uf.operation(--extrinsicState);
	}

}

測試結果:
在這裏插入圖片描述

後分析

  • 個人建議:寫代碼是件幸福的事,So,do it

享元模式,定義:應用共享技術有效地支持大量細粒度的對象。通俗講,就是一類被實例化太多次(這叫大量細粒度的對象),就可以使用共享技術,通過分離內部狀態和外部狀態,即這些實例化對象中共同的代碼作爲內部狀態,有差異的地方作爲外部狀態。這樣就可以只創建少部分的實例化就能實現上述大量細粒度對象才能完成的功能。

享元模式可以避免大量非常類似類的開銷,在程序設計中有時需要生成的阿亮細粒度的類實例來表示數據。如果發現這些實例除了幾個參數外基本上是相同的,有時就能夠大幅度的減少需要實例化的類的數量。如果能把那些參數移到類實例的外面,在方法調用時將他們傳進來,就可以通過共享大幅度地減少單個實例的數目。

舉個例子:圍棋,如果每一個棋子都是一個實例,那一局棋就需要361個實例對象(有361個位置可以放棋子)。N個人同時下棋,那就是Nx361,部署在服務器上,內存有限,無法支持更多的用戶玩耍。那麼這個時候就可以使用享元模式,棋子可以減少到只有兩個實例,黑色和白色。每一個棋子的位置,作爲外部狀態傳入。仔細一想是不是感覺瞬間優化不少。但使用享元模式需要維護一個記錄了系統已有的所有享元的列表(每一次使用享元都需要進行一次查找,即在demo中的map中進行查找),而這本身是消耗資源,也是系統更爲複雜,因此使用享元模式營改增愛有足夠多的對象實例可以共享的時候才值得使用該模式。

其他例子:參考自《大話設計模式》博客網站,每一個用戶都有一個類似界面的博客,總不能每個人都去new一個博客網站的實例,服務器喫不消,那麼共享模式就可以使用了,將有差異的部分移到實例外,將差異在方法調用時傳入即可。


注:以上文章僅是個人總結,若有不當之處,望不吝賜教

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章