最近买了本书,写的不错,推荐一个:《Android源码设计模式解析与实战》
注:本文为本人阅读此书所摘抄写下的笔记,自用!
开闭原则,英文名:Open Close Principle,缩写OCP
定义:类、模块、函数等对于拓展是开放的,但是对于修改是封闭的,当软件需要变化时,应该尽量通过拓展的方式来实现变化,而不是通过修改已有的代码来实现。例如图片缓存通过接口实现可以自由选择使用内存缓存、本地缓存、双缓存还是自定义缓存
MainActivity.Java
四种缓存模式任选其一
ImageLoader imageLoader = new ImageLoader();
//使用内存缓存
imageLoader.setImageCache(new MemoryCache());
//使用sd卡缓存
imageLoader.setImageCache(new DiskCache());
//使用双缓存
imageLoader.setImageCache(new DoubleCache());
//使用自定义缓存
imageLoader.setImageCache(new ImageCache() {
@Override
public Bitmap get(String url) {
return null; //从缓存中获取图片
}
@Override
public void put(String url, Bitmap bmp) {
//缓存图片
}
});
imageLoader.displayImage(url,ivimg);
图片加载类ImageLoader.java
//图片缓存
ImageCache mImageCache = new MemoryCache();
//线程池,线程数量为CPU数量
ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
//注入缓存实现
public void setImageCache(ImageCache cache){
mImageCache = cache;
}
public void displayImage(String imageUrl, ImageView imageView){
Bitmap bitmap = mImageCache.get(imageUrl);
if(bitmap != null){
imageView.setImageBitmap(bitmap);
return;
}
//图片没有缓存,提交到线程池中下载图片
submitLoadRequest(imageUrl,imageView);
}
private void submitLoadRequest(final String imageUrl, final ImageView imageView) {
imageView.setTag(imageUrl);
mExecutorService.submit(new Runnable() {
@Override
public void run() {
Bitmap bitmap = downloadImage(imageUrl);
if(bitmap == null){
return;
}
if(imageView.getTag().equals(imageUrl)){
imageView.setImageBitmap(bitmap);
}
mImageCache.put(imageUrl,bitmap);
}
});
}
private Bitmap downloadImage(String imageUrl) {
Bitmap bitmap = null;
try{
URL url = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
bitmap = BitmapFactory.decodeStream(conn.getInputStream());
conn.disconnect();
}catch (Exception e){
e.printStackTrace();
}
return bitmap;
}
*接口ImageCache.java
*
public interface ImageCache {
public Bitmap get(String url);
public void put(String url, Bitmap bmp);
}
MemoryCache.java`
public class MemoryCache implements ImageCache {
private LruCache<String, Bitmap> mMemeryCache;
public MemoryCache() {
initImageCache();
}
private void initImageCache() {
//计算可使用的最大内存
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
//取四分之一的可用内存为缓存内存
int cacheSize = maxMemory / 4;
mMemeryCache = new LruCache<String, Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
};
}
@Override
public Bitmap get(String url) {
return mMemeryCache.get(url);
}
@Override
public void put(String url, Bitmap bmp) {
mMemeryCache.put(url,bmp);
}
}
DiskCache.java`
public class DiskCache implements ImageCache {
static String cacheDir = "sdcard/cache/";
//从缓存中获取图片
public Bitmap get(String url){
return BitmapFactory.decodeFile(cacheDir + url);
}
//将图片缓存到内存中
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){
}finally{
if (fileOutputStream != null){
try{
fileOutputStream.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
DoubleCache.java`
public class DoubleCache implements ImageCache{
ImageCache mMemoryCache = new MemoryCache();
ImageCache mDiskCache = new DiskCache();
public Bitmap get(String url){
Bitmap bitmap = mMemoryCache.get(url);
if(bitmap == null){
bitmap = mDiskCache.get(url);
}
return bitmap;
}
public void put(String url, Bitmap bitmap){
mDiskCache.put(url, bitmap);
mMemoryCache.put(url, bitmap);
}
}
由上面可以看出,通过接口实现可以自由选择使用内存缓存、本地缓存、双缓存还是自定义缓存,这样,我们可以在不修改代码的基础上灵活使用不同的缓存方法