2_开闭原则

开闭原则

(Open Close Principle, OCP)

参考《Android 源码设计模式》


  • 对扩展开放,对修改关闭。策略,可扩展
  • 策略模式,模式多了不好记:用枚举插一手。算了,如果这样干,增加策略的时候,需要修改枚举类。

单一职责原则 + 开闭原则 + 策略模式,增强 ImageLoader

/** 接口如其名,定义图片缓存顶层接口 */
public interface ImageCache {

    /** 从缓存中获取图片 */
    Bitmap getBitmap(String key);

    /** 缓存图片 */
    void setBitmap(String key, Bitmap bitmap);
}

    /** 内存缓存策略 */   
    public class MemoryCache implements ImageCache {

    /** 使用 LruCache 缓存图片到内存 */
    private static LruCache<String,Bitmap> mLruCache = new LruCache<String,Bitmap>((int) (Runtime.getRuntime().maxMemory() / 4)) {
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            return bitmap.getRowBytes() * bitmap.getHeight();
        }
    };

    @Override
    public Bitmap getBitmap(String key) {
        return mLruCache.get(key);
    }

    @Override
    public void setBitmap(String key, Bitmap bitmap) {
        mLruCache.put(key, bitmap);
    }
}

/** 本地缓存策略 */   
public class DiskCache implements ImageCache {

    /** 使用 DiskLruCache 缓存图片到硬盘 */
    private DiskLruCache mDiskLruCache;

    public DiskCache() {
        initDiskLruCache(); // 初始化 DiskLruCache
    }

    /** 初始化 DiskLruCache */
    private void initDiskLruCache() {
        Context context = AppDemoApplication.getContext();
        // 参数一:可写的缓存目录
        File directory = AppDemoApplication.getContext().getCacheDir();
        // 参数二:
        int appVersion = 1;
        try {
            appVersion = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        // 参数三:最大可缓存文件个数
        int valueCount = 100;
        // 参数四:最大缓存容量 Bytes
        long maxSize= 30 * 1024 * 1024; // 30M

        try {
            mDiskLruCache = DiskLruCache.open(directory, appVersion, valueCount, maxSize);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Bitmap getBitmap(String key) {
        try {
            DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
            if (snapShot != null) {
                InputStream is = snapShot.getInputStream(0);
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                return bitmap;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void setBitmap(String key, Bitmap bitmap) {
        try {
            DiskLruCache.Editor editor = mDiskLruCache.edit(key);
            if (editor != null) {
                editor.commit();
            } else {
                editor.abort();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/** 双缓存策略 */    
public class DoubleCache implements ImageCache {

    private MemoryCache mMemoryCache;
    private DiskCache mDiskCache;

    public DoubleCache() {
        mMemoryCache = new MemoryCache();
        mDiskCache = new DiskCache();
    }

    @Override
    public Bitmap getBitmap(String key) {
        Bitmap bitmap = mMemoryCache.getBitmap(key);
        if (bitmap != null) {
            return bitmap;
        }
        return mDiskCache.getBitmap(key);
    }

    @Override
    public void setBitmap(String key, Bitmap bitmap) {
        mMemoryCache.setBitmap(key, bitmap);
        mDiskCache.setBitmap(key, bitmap);
    }
}

public class ImageLoader {

    /** 默认使用内存缓存的策略 */
    private ImageCache mImageCache = new MemoryCache();

    /** 修改策略的接口 */
    public void setImageCache(ImageCache imageCacheStrategy) {
        mImageCache = imageCacheStrategy;
    }

    /** 对外调用,使用展示网络图片 */
    public void display(final String url, ImageView imageView) {
        Bitmap bitmap = mImageCache.getBitmap(url);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
        } else {
            downloadBitmap(url, imageView);
        }
    }

    private void downloadBitmap(final String url, final ImageView imageView) {
        Downloader downloader = new BitmapDownloader();
        downloader.download(url, new Downloader.Callback<Bitmap>() {
            @Override
            public void success(Bitmap bitmap) {
                imageView.setImageBitmap(bitmap);
            }

            @Override
            public void failed() {

            }
        });
    }
}

——-下载职责分离——

public interface Downloader<X> {

    void download(String url, Callback<X> callback);

    interface Callback<Y> {
        void success(Y y);
        void failed();
    }
}

public class BitmapDownloader implements Downloader<Bitmap> {

    @Override
    public void download(String url, final Callback<Bitmap> callback) {
        OkGo.<Bitmap>get(url)
                .tag(this)
                .execute(new BitmapCallback() {
                    @Override
                    public void onSuccess(Response<Bitmap> response) {
                        callback.success(response.body());
                    }
                });
    }
}

public class StringDownLoader implements Downloader<String> {

    @Override
    public void download(String url, final Callback<String> callback) {
        OkGo.<String>get(url)
                .tag(this)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(Response<String> response) {
                        callback.success(response.body());
                    }
                });
    }
}

——–最后呈现给客户端———–

public class ClientActivity extends Activity {

    private ImageView mImageView;
    private ImageLoader mImageLoader;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_client);

        mImageView = (ImageView) findViewById(R.id.image);

        mImageLoader = new ImageLoader();
        /* 采用默认的内存缓存策略 */
        mImageLoader.display("http://127.0.0.1:8080/wahaha.png", mImageView);

        /* 采用内存缓存策略 */
        mImageLoader.setImageCache(new MemoryCache());
        mImageLoader.display("http://127.0.0.1:8080/wahaha.png", mImageView);

        /* 采用硬盘缓存策略 */
        mImageLoader.setImageCache(new DiskCache());
        mImageLoader.display("http://127.0.0.1:8080/wahaha.png", mImageView);

        /* 采用双缓存策略 */
        mImageLoader.setImageCache(new DoubleCache());
        mImageLoader.display("http://127.0.0.1:8080/wahaha.png", mImageView);
    }
}

如上为采用“开闭原则”,配合策略模式的小示例!

猜你喜欢

转载自blog.csdn.net/wq316476051/article/details/74783416