《研磨设计模式》chap20 享元模式 Flyweight (4)总结
生活随笔
收集整理的這篇文章主要介紹了
《研磨设计模式》chap20 享元模式 Flyweight (4)总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1. 不共享的外部狀態
輸入數據為:
張三,人員列表,查看,1
李四,人員列表,查看,1
李四,操作薪資數據,2
" 操作薪資數據"包括"薪資數據,查看",“薪資數據,修改”
public class UnsharedConcreteFlyweight implements Flyweight{//記錄每個組合對象所包含的子組件 private List<Flyweight> list = new ArrayList<Flyweight>(); public void add(Flyweight f) {list.add(f);} public boolean match(String securityEntity, String permit) {for(Flyweight f : list){//遞歸調用if(f.match(securityEntity, permit)){return true;}}return false;} }public class AuthorizationFlyweight implements Flyweight{... public void add(Flyweight f) {throw new UnsupportedOperationException("對象不支持這個功能");} }public class SecurityMgr {...//從數據庫中獲取某人所擁有的權限 private Collection<Flyweight> queryByUser(String user){Collection<Flyweight> col = new ArrayList<Flyweight>(); for(String s : TestDB.colDB){String ss[] = s.split(",");if(ss[0].equals(user)){Flyweight fm = null;if(ss[3].equals("2")){//表示是組合fm = new UnsharedConcreteFlyweight();//獲取需要組合的數據String tempSs[] = TestDB.mapDB.get(ss[1]);for(String tempS : tempSs){Flyweight tempFm = FlyweightFactory.getInstance().getFlyweight(tempS);//把這個對象加入到組合對象中fm.add(tempFm);}}else{fm = FlyweightFactory.getInstance().getFlyweight(ss[1]+","+ss[2]);}col.add(fm);}}return col;} }public class TestDB { ...static{//通過靜態塊來填充模擬的數據,增加一個標識來表明是否組合授權數據colDB.add("張三,人員列表,查看,1");colDB.add("李四,人員列表,查看,1");colDB.add("李四,操作薪資數據,,2"); mapDB.put("操作薪資數據",new String[]{"薪資數據,查看","薪資數據,修改"});//增加更多的授權數據for(int i=0;i<3;i++){colDB.add("張三"+i+",人員列表,查看,1");}} }2. 對享元對象的管理:引用計數、時間有效
public class CacheConfModel{//緩存開始計時的開始時間 private long beginTime;//緩存對象存放的持續時間,其實是最長不被使用的時間 private double durableTime;//緩存對象需要被永久存儲,也就是不需要從緩存中刪除 private boolean forever; }public class FlyweightFactory { private FlyweightFactory(){//啟動清除緩存值的線程Thread t = new ClearCache();t.start();} //緩存多個flyweight對象 private Map<String,Flyweight> fsMap = new HashMap<String,Flyweight>();//用來緩存被共享對象的緩存配置,key值和上面map的一樣 private Map<String,CacheConfModel> cacheConfMap = new HashMap<String,CacheConfModel>();//用來記錄緩存對象被引用的次數,key值和上面map的一樣 private Map<String,Integer> countMap = new HashMap<String,Integer>();//默認保存6秒鐘 private final long DURABLE_TIME = 6*1000L; //獲取某個享元被使用的次數 public synchronized int getUseTimes(String key){Integer count = countMap.get(key);if(count==null){count = 0;}return count;}//獲取key對應的享元對象 public synchronized Flyweight getFlyweight(String key) {Flyweight f = fsMap.get(key);//換一個更簡單點的寫法if(f==null){f = new AuthorizationFlyweight(key);fsMap.put(key,f);//同時設置引用計數countMap.put(key, 1);//同時設置緩存配置數據CacheConfModel cm = new CacheConfModel();cm.setBeginTime(System.currentTimeMillis());cm.setForever(false);cm.setDurableTime(DURABLE_TIME);cacheConfMap.put(key, cm);}else{//表示還在使用,那么應該重新設置緩存配置CacheConfModel cm = cacheConfMap.get(key);cm.setBeginTime(System.currentTimeMillis());//設置回去this.cacheConfMap.put(key, cm);//同時計數加1Integer count = countMap.get(key);count++;countMap.put(key, count);}return f;}//刪除key對應的享元對象 private synchronized void removeFlyweight(String key){this.fsMap.remove(key);this.cacheConfMap.remove(key);this.countMap.remove(key);}//維護清除緩存的線程,內部使用 private class ClearCache extends Thread{public void run(){while(true){Set<String> tempSet = new HashSet<String>();Set<String> set = cacheConfMap.keySet();for(String key : set){CacheConfModel ccm = cacheConfMap.get(key);//比較是否需要清除if((System.currentTimeMillis()-ccm.getBeginTime())>= ccm.getDurableTime()){//可以清除,先記錄下來tempSet.add(key);}}//真正清除for(String key : tempSet){FlyweightFactory.getInstance().removeFlyweight(key); }System.out.println("now thread="+fsMap.size()+",fsMap=="+fsMap.keySet());//休息1秒再重新判斷try {Thread.sleep(1000L);} catch (InterruptedException e) {e.printStackTrace();}}}} }3. 總結
享元模式的本質:分離與共享。
分離的是對象狀態中變與不變的部分,共享的是對象中不變的部分。享元模式的關鍵之處就在于分離變與不變,把不變的部分作為享元對象的內部狀態,而變化部分則作為外部狀態,由外部來維護,這樣享元對象就能夠被共享,從而減少對象數量,并節省大量的內存空間。
理解了這個本質后,在使用享元模式的時候,就會考慮,哪些狀態需要分離?如何分離?分離后如何處理?哪些需要共享?如何管理共享的對象?外部如何使用共享的享元對象?是否需要不共享的對象?等等。
總結
以上是生活随笔為你收集整理的《研磨设计模式》chap20 享元模式 Flyweight (4)总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《研磨设计模式》chap20 享元模式
- 下一篇: 《研磨设计模式》chap21 解释器模式