參考自:https://blog.csdn.net/justloveyou_/article/details/55045638
存在的意義:物件導向技術可以很好地解決一些靈活性或可擴充性問題,但在很多情況下需要在系統中增加類和對象的個數。當對象數量太多時,將導致運行代價過高,帶來效能下降等問題。享元模式正是為解決這一類問題而誕生的。
內部狀態(Intrinsic State):在享元模式中可以共用的相同內容
外部狀態(Extrinsic State):需要外部環境來設定的不能共用的內容
在實際使用中,能夠共用的內部狀態是有限的,因此享元對象一般都設計為較小的對象,它所包含的內部狀態較少,這種對象也稱為細粒度對象。
由於 享元模式要求能夠共用的對象必須是細粒度對象,因此它又稱為輕量級模式,它是一種 對象結構型模式。
模式結構:
單純享元模式:在單純享元模式中,所有的享元對象都是可以共用的,即所有抽象享元類的子類都可共用,不存在非共用具體享元類。
步驟一:建立一個抽象享元介面
//抽象享元角色類public interface FlyWeight {//一個示意性方法,參數externalState是外蘊狀態 void action(String externalState);}
步驟二:建立具體享元角色類
//具體享元角色類public class ConcreteFlyWeight implements FlyWeight {//內蘊狀態private String name;//建構函式,內蘊狀態作為參數傳入public ConcreteFlyWeight(String name) {this.name=name;}// 外蘊狀態 externalState作為參數傳入方法中,改變方法的行為,但是並不改變對象的內蘊狀態name。public void action(String externalState) { System.out.println(" 內蘊狀態= " + this.name); System.out.println("外蘊狀態 = " + externalState);}}
步驟三:建立一個享元工廠
//享元工廠角色類public class FlyWeightFactory { private static final Logger log=LoggerFactory.getLogger(FlyWeightFactory.class); private static ConcurrentHashMap<String,FlyWeight> allFlyWeight=new ConcurrentHashMap<String,FlyWeight>(); public static FlyWeight getFlyWeight(String name) { if(allFlyWeight.get(name)==null) { synchronized(allFlyWeight) { if(allFlyWeight.get(name)==null) { System.out.println("執行個體名不存在,執行建立"); FlyWeight flyweight=new ConcreteFlyWeight(name); System.out.println("建立完成"); allFlyWeight.put(name, flyweight); } } } return allFlyWeight.get(name); }}
步驟四:測試
public class Test {public static void main(String[] args) { FlyWeightFactory factory=new FlyWeightFactory(); //申請三個享元對象A,B,B(但是實際建立只有兩個) FlyWeight fly=factory.getFlyWeight("A"); fly.action("建立一個對象A"); fly=factory.getFlyWeight("B"); fly.action("建立一個對象B"); fly=factory.getFlyWeight("B"); fly.action("建立一個對象B");} }
複合享元模式:將一些單純享元使用組合模式加以組合,可以形成複合享元對象,這樣的複合享元對象本身不能共用,但是它們可以分解成單純享元對象,而後者則可以共用。
步驟一:建立抽象享元介面
//抽象享元角色類public interface FlyWeight {//一個示意性方法,參數externalState是外蘊狀態 void action(String externalState);}
步驟二:建立單純具體享元角色類
//具體享元角色類public class ConcreteFlyWeight implements FlyWeight {//內蘊狀態private String name;//建構函式,內蘊狀態作為參數傳入public ConcreteFlyWeight(String name) {this.name=name;}// 外蘊狀態 externalState作為參數傳入方法中,改變方法的行為,但是並不改變對象的內蘊狀態name。public void action(String externalState) { System.out.println(" 內蘊狀態= " + this.name); System.out.println("外蘊狀態 = " + externalState);}}
步驟二:建立複合具體享元角色類
public class ConcreteCompositeFlyweight implements FlyWeight {private Map<String,FlyWeight> map=new HashMap<String,FlyWeight>();//增加一個新的單純享元對象到聚集中public void add(String name,FlyWeight fly) {map.put(name, fly);}@Overridepublic void action(String externalState) { FlyWeight fly = null; for(Object o:map.keySet()) { fly=map.get(o); fly.action("執行-----(外蘊狀態)"); }} }
步驟三:建立享元工廠
//享元工廠角色類public class FlyWeightFactory { private static ConcurrentHashMap<String,FlyWeight> allFlyWeight=new ConcurrentHashMap<String,FlyWeight>(); //複合享元Factory 方法(接收的是一個List集合參數的內蘊狀態(鍵),遍曆來get到對應的享元對象) public FlyWeight getCompositeFlyWeight(List<String> compositestate) { ConcreteCompositeFlyweight compository=new ConcreteCompositeFlyweight(); for(String state:compositestate) { compository.add(state, this.getFlyWeight(state)); }return compository; } //單純享元Factory 方法 public static FlyWeight getFlyWeight(String name) { if(allFlyWeight.get(name)==null) { synchronized(allFlyWeight) { if(allFlyWeight.get(name)==null) { System.out.println("執行個體名不存在,執行建立"); FlyWeight flyweight=new ConcreteFlyWeight(name); System.out.println("建立完成"); allFlyWeight.put(name, flyweight); } } } return allFlyWeight.get(name); }}
步驟四:測試
public class Test {public static void main(String[] args) {List<String> compositestate=new ArrayList<String>();compositestate.add("A");compositestate.add("B");compositestate.add("C");compositestate.add("C");FlyWeightFactory flyFactory=new FlyWeightFactory();FlyWeight compositeFly1= flyFactory.getCompositeFlyWeight(compositestate);FlyWeight compositeFly2= flyFactory.getCompositeFlyWeight(compositestate);compositeFly1.action("複合享元模式-----");System.out.println("----------");System.out.println("複合享元對象是否共用對象:"+(compositeFly1==compositeFly2));String state="hello";FlyWeight fly1=flyFactory.getFlyWeight(state);FlyWeight fly2=flyFactory.getFlyWeight(state);System.out.println("單純享元對象是否共用對象:"+(fly1==fly2));} }