面向对象--单一职责原则和开闭原则学习(简易ImageLoader)

来源:互联网 发布:人力资源数据分析模型 编辑:程序博客网 时间:2024/06/08 17:11

一、概述

这篇是读《Android源码设计模式解析与实战》的第一篇记录,今天学习了面向对象六大原则中的其二:单一职责原则和开闭原则。单一职责原则简单来说一个类只实现一个功能;开闭原则则是对于扩展是开放的,对于修改是关闭的。这些原则都是用来优化代码的。

二、简易ImageLoader实现

下面通过一个简单的ImageLoader来说明编码过程中的以上两个原则。
首先,一个ImageLoader主要分为两部分,一部分为图片加载,另一部分为图片缓存,这就可以提示我们可以将功能分为两个类分别实现(单一职责原则)。同时,缓存可分为内存缓存、存储缓存以及双缓存,甚至以后还可能有什么缓存技术,但其作用都是取出和存入两项功能,为了方便扩展,我们将取出和存入抽象出一个接口来实现(开闭原则)。

三、代码展示

缓存接口:

public interface ImageCache {    public void put(String url, Bitmap bitmap);    public Bitmap get(String url);}

内存缓存接口实现:

public class MemoryCache implements ImageCache {    LruCache<String, Bitmap> mMemoryCache;    public MemoryCache() {        initMemoryCache();    }    private void initMemoryCache() {        // 计算可使用的最大内存,单位KB        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);        // 通常取四分之一的可用内存作为缓存        final int cacheSize = maxMemory / 4;        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {            @Override            protected int sizeOf(String key, Bitmap value) {                return value.getRowBytes() * value.getHeight() / 1024;            }        };    }    @Override    public void put(String url, Bitmap bitmap) {        mMemoryCache.put(url, bitmap);    }    @Override    public Bitmap get(String url) {        return mMemoryCache.get(url);    }}

存储缓存接口实现:

public class DiskCache implements ImageCache {    private static final String cacheDir = "sdcard/cache/";    @Override    public void put(String url, Bitmap bitmap) {        FileOutputStream fileOutputStream = null;        try {            fileOutputStream = new FileOutputStream(cacheDir + url);            // 将图片进行压缩            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);        } catch (FileNotFoundException e) {            e.printStackTrace();        } finally {            if (fileOutputStream != null) {                try {                    fileOutputStream.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }    @Override    public Bitmap get(String url) {        return BitmapFactory.decodeFile(cacheDir + url);    }}

双缓存接口实现:

public class DoubleCache implements ImageCache {    ImageCache mMemoryCache = new MemoryCache();    ImageCache mDiskCache = new DiskCache();    @Override    public void put(String url, Bitmap bitmap) {        mMemoryCache.put(url, bitmap);        mDiskCache.put(url, bitmap);    }    // 先从内存缓存中获取图片,如果没有,再从sd卡中获取    @Override    public Bitmap get(String url) {        Bitmap bitmap = mMemoryCache.get(url);        if (bitmap == null) {            bitmap = mDiskCache.get(url);        }        return bitmap;    }}

图片加载类:

public class ImageLoader {    ImageCache mImageCache = new MemoryCache();    ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());    // 注入缓存实现    public void setImageCache(ImageCache imageCache) {        this.mImageCache = imageCache;    }    public void displayImage(String url, ImageView imageView) {        Bitmap bitmap = mImageCache.get(url);        if (bitmap != null) {            imageView.setImageBitmap(bitmap);            return;        }    }    private void submitLoadRequest(final String url, final ImageView imageView) {        imageView.setTag(url);        mExecutorService.submit(new Runnable() {            @Override            public void run() {                Bitmap bitmap = downloadImage(url);                if (bitmap == null) {                    return;                }                if (imageView.getTag().equals(url)) {                    imageView.setImageBitmap(bitmap);                }                mImageCache.put(url, bitmap);            }        });    }    private Bitmap downloadImage(String imageUrl) {        Bitmap bitmap = null;        try {            URL url = new URL(imageUrl);            final HttpURLConnection conn = (HttpURLConnection) url.openConnection();            bitmap = BitmapFactory.decodeStream(conn.getInputStream());            // 记得断开链接            conn.disconnect();        } catch (Exception e) {            e.printStackTrace();        }        return bitmap;    }}

四、总结

以上就是通过一个简易的ImageLoader来学习单一职责原则和开闭原则的过程,在平时功能设计和编码时都要时刻注意。项目中使用的ImageLoader会更为复杂,有兴趣的可参考一些优秀的第三方开源库源码进行学习。

0 0
原创粉丝点击