运用共享技术有效地支持大量细粒度的对象。
当一个应用中使用了大量的对象,这些对象造成了很大的存储开销,而对象的大部分状态或参数都是相同(内部状态)的时候,可以考虑使用享元模式,使用享元模式可以使这些对象引用都共享相同的实例,降低存储开销,而对象之间的不同的状态参数(外部状态)则使用外部参数传入来实现。
抽象享元(FlyWeight)角色:所有具体享元角色需要实现的接口。那些需要外在状态(externalState)的操作可以通过参数的形式传入。
具体享元(Concrete FlyWeight)角色:实现抽象享元角色所规定出的接口。如果有内在状态(internalState)的话,必须负责为内在状态提供存储空间。内在状态必须与对象所处的周围环境无关,从而使得享元对象可以再系统中共享。
享元工厂(FlyWeight Factory)角色 :本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。
interface FlyWeight{ public void operation(String externalState); } class ConcreteFlyWeight implements FlyWeight{ private String intenalState=null; public ConcreteFlyWeight(String intenalState){ this.intenalState=intenalState; } @Override public void operation(String externalState){ System.out.println("内在状态:"+intenalState); System.out.println("外在状态:"+externalState); } } class FlyWeightFactory{ private Map<String,FlyWeight> flyWeights=new HashMap<String,FlyWeight>(); public FlyWeight getFlyWeight(String intenalState){ if(flyWeights.containsKey(intenalState)){ return (FlyWeight)flyWeights.get(intenalState); }else{ FlyWeight fly=new ConcreteFlyWeight(intenalState); flyWeights.put(intenalState,fly); return fly; } } public int getSize(){ return flyWeights.size(); } }
//抽象享元 interface Word{ public void operation(int weight); } //具体享元 class ChinaWord implements Word{ private String value=null; public ChinaWord(String value){ this.value=value; } @Override public void operation(int weight){ System.out.println("词汇:"+value); System.out.println("权重:"+weight); } } class EnglishWord implements Word{ private String value=null; public EnglishWord(String value){ this.value=value; } @Override public void operation(int weight){ System.out.println("词汇:"+value); System.out.println("权重:"+weight); } } //享元工厂 class Directory{ private Map<String,Word> wordMap=new HashMap<String,Word>(); public Word getWord(String value){ if(wordMap.containsKey(value)){ return (Word)wordMap.get(value); }else{ Word w=null; if(value.charAt(0)>='a'&&value.charAt(0)<='z') w=new EnglishWord(value); else w=new ChinaWord(value); wordMap.put(value,w); return w; } } public int getSize(){ return wordMap.size(); } }
//客户端代码 class test { public static void main (String[] args) throws java.lang.Exception{ Directory directory=new Directory(); String[] words={"this","is","a","dog","this","is","a","cat","这","是","一个","小猫","这","是","一个","小狗"}; List<Word> ws=new ArrayList<Word>(); for(String s:words){ ws.add(directory.getWord(s)); } System.out.println(directory.getSize()); ws.get(0).operation(6); } }