二十一、享元设计模式

1. 享元设计模式介绍

享元模式用来尽可能减少内存使用量,它适合用于可能存在大量重复对象的场景,用来缓存可共享的对象,达到对象共享、避免创建过多对象的效果。

定义:

使用共享对象可有效地支持大量的细粒度对象。

2. 享元设计模式使用场景

  • 如果一个系统中存在大量的相同或者相似的对象,由于这类对象的大量使用,会造成系统内存的消耗,可以使用享元模式来减少系统中对象的数量。
  • 对象的大部分状态都可以外部化,可这些外部状态传入对象。

3. 享元设计模式UML类图

享元设计模式UML类图

角色介绍

  • FlyWeight:享元对象抽象基类或者接口
  • ConcreteFlyweight:具体的享元对象
  • FlyweightFactory:享元工厂,负责管理享元对象池和创建享元对象

4. 享元设计模式简单实现

场景如下: 我们现在需要加载图片,如果已经加载过图片了,就直接读取本地缓存,如果没有加载过图片,从网络中保存图片,以图片地址为key。

  • (1)、首先定义一个接口:
public interface Pic {
    public void showInfo();
}

showInfo方法用来展示图片信息

  • (2)、Bitmap图片类,实现Pic接口:
public class Bitmap implements Pic {
    private String src; //图片地址

    public Bitmap(String src) {
        this.src = src;
    }

    @Override
    public void showInfo() {
        System.out.println(src);
    }
}
  • (3)、BitmapFactory。图片工厂类
public class BitmapFactory {
            private Map<String, Bitmap> imgs = new ConcurrentHashMap<String, Bitmap>();
            private Bitmap bitmap;

            public Bitmap getBitmap(String src) {
                if (imgs.get(src) == null) {
                    bitmap = new Bitmap(src);
                    imgs.put(src, bitmap);
                    System.out.println("加载网络.");
                } else {
                    bitmap = imgs.get(src);
                    System.out.println("加载本地.");
                }
                return bitmap;
            }
        }

如果本地有图片,从本地取出;如果没有图片,联网,存入本地。

  • (4)、测试类:
public class Client {
            public static void main(String[] args) {
                BitmapFactory bitmapFactory = new BitmapFactory();
                Bitmap bitMap1 = bitmapFactory.getBitmap("图片1");
                bitMap1.showInfo();
                Bitmap bitMap2 = bitmapFactory.getBitmap("图片2");
                bitMap2.showInfo();
                Bitmap bitMap1_1 = bitmapFactory.getBitmap("图片1");
                bitMap1_1.showInfo();
            }
        }

结果如下:

        加载网络.
        图片1
        加载网络.
        图片2
        加载本地.
        图片1

可以看到,第一次创建后,第三次取出同样的图片时,加载的是本地图片。

5. 享元设计模式在Android源码中

享元模式在Android源码也比较常见,比如ListView的convertView。

在getView时,判断convertView是不是null,如果等于null,才会调用inflate()方法来加载布局,不等于null就直接利用convertView。

convertView是我们之前用过的View,只不过移除了屏幕后进入了废弃的缓存中。当convertView不等于null时,将其重新拿出来使用。

ListView享元

6. 总结

享元模式用来尽可能减少内存使用量,它适合用于可能存在大量重复对象的场景,来缓存可共享的对象,达到对象共享、避免创建过多对象的效果。

  • 优点:
    • 大幅度降低内存中对象的数量,减少内存开销。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值