享元模式(FlyWeight)-结构型

意图

运用共享技术有效地支持大量细粒度的对象。

适用场景

当一个应用中使用了大量的对象,这些对象造成了很大的存储开销,而对象的大部分状态或参数都是相同(内部状态)的时候,可以考虑使用享元模式,使用享元模式可以使这些对象引用都共享相同的实例,降低存储开销,而对象之间的不同的状态参数(外部状态)则使用外部参数传入来实现。

类图与角色

享元模式(FlyWeight)-结构型_第1张图片

抽象享元(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();
    }
}

实例

比如说一个文本系统,我们需要将每个英文单词或每个中文词组当做一个Word对象。如果有一个10 M的文本,如果每遇到一个单词或词组都定义一个新的Word对象,那么需要消耗大量的内存。如果将相同的单词共享一个Word对象,那么就大大节约了资源。
//抽象享元
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);
	}
}


你可能感兴趣的:(享元模式,Flyweight模式)