2_开闭原则

来源:互联网 发布:nodejs 数组排序 编辑:程序博客网 时间:2024/05/22 17:09

开闭原则

(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);    }}

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

原创粉丝点击