设计模式——享元模式

个人理解:

1. 享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

2. 享元模式可以看做是一个对象池,存放的都是单例对象,是不重复的,如果我们创建一个对象,正好对象池里面已经存在,就直接复用即可,不需要重新创建。如果创建的对象对象池里面没有,就创建一个对象加入这个对象池,方便下次使用。

3. 享元模式可分为:单纯享元模式、复合享元模式

 (1)单纯享元:所有的享元对象都是单纯享元对象,也就是说都是可以直接共享的,单纯享元UML图如下:


 (2)复合享元:将一些单纯享元使用合成模式加以复合,形成复合享元对象。这样的复合享元对象本身不能共享,但是组成复合享元的单纯享元可以内部共享。复合享元UML图如下:

4. 享元存储情况:

(1)单纯享元模式具体享元存储于享元工厂FlyweightFactory类的Map集合中;

(2)在示例代码中,复合享元模式的具体享元有两种存储情况:

a. 通过复合享元的addWord(String key) 存储,在复合享元中创建共享的单纯享元,仅在复合享元的Map集合中存储单纯享元

b. 通过复合享元的addWord(Word word) 存储,在享元工厂中创建共享的单纯享元,在享元工厂的Map集合&&复合享元的Map集合中都有存储单纯享元

5. 示例代码:

抽象享元:Flyweight:

public abstract class Word {

    String content;

    public String getContent() {
        return content;
    }

    public abstract void showWord(String str);

}

具体享元ConcreteFlyweight(单纯享元、复合享元):

public class WordShow extends Word {

    public WordShow(String content) {
        this.content = content;
    }

    @Override
    public void showWord(String str) {
        Log.i("showWord", "------" + content + str + "------");
    }
}

复合享元ConcreteCompositeFlyweight(复合享元):

public class WordShowComplex extends Word {

    private Map<String , Word> wordMap = new HashMap();

    @Override
    public void showWord(String str) {
        Word word = null;
        for (String wordKey : wordMap.keySet()){
            word = wordMap.get(wordKey);
            word.showWord(str);
        }
    }

    public void addWord(Word word){
        wordMap.put(word.getContent(), word);
    }

    public void addWord(String key){
        if (TextUtils.isEmpty(key)){
            Log.i("getWordShow", "传入Key值为空");
            return;
        }
        if (!wordMap.containsKey(key)){
            wordMap.put(key, new WordShow(key));
        }
    }

    public int getCount(){
        return wordMap.size();
    }
}

享元工厂FlyweightFactory:

public class WordFactory {

    private Map<String, Word> wordMap = new HashMap<>();
    WordShowComplex wordShowComplex;

    public Word getWordShow(String key){
        if (TextUtils.isEmpty(key)){
            Log.i("getWordShow", "传入Key值为空");
            return null;
        }
        if (!wordMap.containsKey(key)){
            wordMap.put(key, new WordShow(key));
        }
        return wordMap.get(key);
    }

    public int getWordCounts(){
        return wordMap.size();
    }

    public Word getWordShowComplex(List<String> keyList){
        wordShowComplex = new WordShowComplex();
        for (String key : keyList){
            wordShowComplex.addWord(new WordShow(key));
//            wordShowComplex.addWord(key);
        }
        return wordShowComplex;
    }

    public int getWordShowComplexCount(){
        return wordShowComplex.getCount();
    }
}

客户端调用:

private void factoryFlyweight(){
        WordFactory wordFactory = new WordFactory();
        Word wordA1 = wordFactory.getWordShow("张华说:");
        wordA1.showWord("天王盖地虎");
        Log.i("factoryFlyweight", "****************单纯享元模式WorFactory中Word数量:" + wordFactory.getWordCounts()+ "****************");
        Word wordA2 = wordFactory.getWordShow("张华说:");
        wordA2.showWord("宝塔镇河妖");
        Log.i("factoryFlyweight", "****************单纯享元模式WorFactory中Word数量:" + wordFactory.getWordCounts()+ "****************");
        Word wordB = wordFactory.getWordShow("赵鹏说:");
        wordB.showWord("玉帝X王母");
        Log.i("factoryFlyweight", "****************单纯享元模式WorFactory中Word数量:" + wordFactory.getWordCounts()+ "****************");
        Log.i("factoryFlyweight", "****************单纯享元模式是否可以共享对象:" + (wordA1 == wordA2) + "****************");

        List<String> words = new ArrayList<>();
        words.add("张华说:");
        words.add("李帅说:");
        words.add("赵鹏说:");
        Word wordC1 = wordFactory.getWordShowComplex(words);
        wordC1.showWord("吃葡萄不吐葡萄皮");
        Log.i("factoryFlyweight", "****************复合享元模式WorFactory wordC1中Word数量:" + wordFactory.getWordShowComplexCount()+ "****************");
        Word wordC2 = wordFactory.getWordShowComplex(words);
        wordC2.showWord("不吃葡萄倒吐葡萄皮");
        Log.i("factoryFlyweight", "****************复合享元模式WorFactory wordC2中Word数量:" + wordFactory.getWordShowComplexCount()+ "****************");

        Log.i("factoryFlyweight", "****************复合享元模式是否可以共享对象:" + (wordC1 == wordC2) + "****************");
    }
}

运行结果:

12-14 17:42:09.842 1473-1473/com.wdp.designtest I/showWord: ------张华说:天王盖地虎------
12-14 17:42:09.843 1473-1473/com.wdp.designtest I/factoryFlyweight: ****************单纯享元模式WorFactory中Word数量:1****************
12-14 17:42:09.843 1473-1473/com.wdp.designtest I/showWord: ------张华说:宝塔镇河妖------
12-14 17:42:09.843 1473-1473/com.wdp.designtest I/factoryFlyweight: ****************单纯享元模式WorFactory中Word数量:1****************
12-14 17:42:09.843 1473-1473/com.wdp.designtest I/showWord: ------赵鹏说:玉帝X王母------
12-14 17:42:09.843 1473-1473/com.wdp.designtest I/factoryFlyweight: ****************单纯享元模式WorFactory中Word数量:2****************
12-14 17:42:09.843 1473-1473/com.wdp.designtest I/factoryFlyweight: ****************单纯享元模式是否可以共享对象:true****************
12-14 17:42:09.844 1473-1473/com.wdp.designtest I/showWord: ------赵鹏说:吃葡萄不吐葡萄皮------
12-14 17:42:09.844 1473-1473/com.wdp.designtest I/showWord: ------张华说:吃葡萄不吐葡萄皮------
12-14 17:42:09.844 1473-1473/com.wdp.designtest I/showWord: ------李帅说:吃葡萄不吐葡萄皮------
12-14 17:42:09.844 1473-1473/com.wdp.designtest I/factoryFlyweight: ****************复合享元模式WorFactory wordC1中Word数量:3****************
12-14 17:42:09.844 1473-1473/com.wdp.designtest I/showWord: ------赵鹏说:不吃葡萄倒吐葡萄皮------
12-14 17:42:09.844 1473-1473/com.wdp.designtest I/showWord: ------张华说:不吃葡萄倒吐葡萄皮------
12-14 17:42:09.844 1473-1473/com.wdp.designtest I/showWord: ------李帅说:不吃葡萄倒吐葡萄皮------
12-14 17:42:09.844 1473-1473/com.wdp.designtest I/factoryFlyweight: ****************复合享元模式WorFactory wordC2中Word数量:3****************
12-14 17:42:09.844 1473-1473/com.wdp.designtest I/factoryFlyweight: ****************单纯享元模式WorFactory中Word数量:3****************
12-14 17:42:09.844 1473-1473/com.wdp.designtest I/factoryFlyweight: ****************复合享元模式是否可以共享对象:false****************



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值