学习了何红辉、关爱民写的《Android设计模式》,对于面向对象的六大原则有进一步的理解,特此根据自己的理解记录总结一下
也称为最少知识原则,意思就是一个对象应该对其他对象有最少的了解,其实就是解耦合,两个类之间的关系分离的越细越好,比如面向对象的六大原则之 —— 单一原则中讲的,Imageloader类,它需要缓存,然而缓存ImageCache的具体实现,ImageLoader是不知道的。
我们打个比方,你卖肾跟iphone代理商买了一台 Iphone100 ,结果用了几天,泥马坏了,你是不是应该把手机给回代理商去保修,然而你是不需要知道,人家是怎么保修的,你只需要把手机给回代理商,让人家去保修,其他的你一概不管,保修不好就还肾,就这么简单。
实际运用一下,我们原本的ImageLoader类是直接跟内存缓存打交道的
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.LruCache; import android.widget.ImageView; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by Administrator on 2016/3/1. */ public class ImageLoader { public ImageLoader() { } //图片缓存类 ImageCache imageCache=new ImageCache(); //线程池,线城数量为cpu的数量 ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); /** * 显示图片 * @param url 图片的url * @param imageView 要显示的view */ public void displayImage(final String url, final ImageView imageView) { Bitmap bitmap=imageCache.get(url); if(bitmap!=null){ imageView.setImageBitmap(bitmap); return; } 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); } imageCache.put(url, bitmap); } }); } /** * 下載圖片 * @param imageUrl 网络图片地址 * @return 返回bitmap对象 */ public 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 (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return bitmap; } }
import android.graphics.Bitmap; import android.util.LruCache; /** * Created by Administrator on 2016/3/1. */ public class ImageCache { public ImageCache() { //初始化图片缓存 initImageCache(); } //图片缓存类 LruCache<String, Bitmap> imageCache; /** * 初始化缓存 */ private void initImageCache() { //计算可使用的最大内存 int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); //只用最大内存的四分之一作为缓存大小 int cacheSize = maxMemory / 4; imageCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight() / 1024; } }; } /** * 添加缓存 * * @param url 缓存的图片url作为缓存的key * @param bitmap 缓存的bitmap */ public void put(String url, Bitmap bitmap) { imageCache.put(url, bitmap); } /** * 获取缓存的图片 * * @param url * @return */ public Bitmap get(String url) { Bitmap bitmap = null; bitmap = imageCache.get(url); return bitmap; } }
我们想一下,给个代理商的类
这个代理商类,我们就直接命名为ImageCache,所以,ImageCache现在的内容如下
import android.graphics.Bitmap; /** * Created by Administrator on 2016/3/1. */ public interface ImageCache { /** * 添加缓存 * @param url 缓存的图片url作为缓存的key * @param bitmap 缓存的bitmap */ public void put(String url, Bitmap bitmap); /** * 获取缓存的图片 * @param url * @return */ public Bitmap get(String url); }
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.widget.ImageView; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by Administrator on 2016/3/1. */ public class ImageLoader { public ImageLoader() { } //默认使用内存缓存 ImageCache imageCache=new MemoryCache(); //线程池,线城数量为cpu的数量 ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); /** * 设置要使用哪种缓存 * @param imageCache 缓存类 */ public void setImageCache(ImageCache imageCache) { this.imageCache = imageCache; } /** * 显示图片 * @param url 图片的url * @param imageView 要显示的view */ public void displayImage(final String url, final ImageView imageView) { Bitmap bitmap=imageCache.get(url); if(bitmap!=null){ imageView.setImageBitmap(bitmap); return; } 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); } //添加到缓存 imageCache.put(url, bitmap); } }); } /** * 下載圖片 * @param imageUrl 网络图片地址 * @return 返回bitmap对象 */ public 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 (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return bitmap; } }
import android.graphics.Bitmap; import android.util.LruCache; /** * Created by Administrator on 2016/3/1. */ public class MemoryCache implements ImageCache{ public MemoryCache() { //初始化图片缓存 initImageCache(); } //图片缓存类 LruCache<String, Bitmap> memoryCache; /** * 初始化缓存 */ private void initImageCache() { //计算可使用的最大内存 int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); //只用最大内存的四分之一作为缓存大小 int cacheSize = maxMemory / 4; memoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight() / 1024; } }; } /** * 添加缓存 * * @param url 缓存的图片url作为缓存的key * @param bitmap 缓存的bitmap */ public void put(String url, Bitmap bitmap) { memoryCache.put(url, bitmap); } /** * 获取缓存的图片 * * @param url * @return */ public Bitmap get(String url) { Bitmap bitmap = null; bitmap = memoryCache.get(url); return bitmap; } }
对于上面的解释你可能会比较迷糊,我专业点解释一下,其实就是,我们这个ImageLoader图片加载器原先在实现缓存的时候,是直接跟缓存类ImageCache打交道的,也就说明了,一但我们需要添加新的缓存方式,我们就需要更改ImageLoader里面的代码,这样明显的说明了,两个类之间是有直接关系的,而迪米特原则就是,不要有直接关系,或者说,关系越小越好,所以,我们拆开来,搞了一个中间的接口ImageCache,而真正的实现缓存的MemoryCache内存缓存类,实现了ImageCache接口,在ImageLoader中,我们只需要使用ImageCache接口就行,这样,用户在使用哪一种缓存的时候,只要实现ImageCache接口就能实现自己想要的缓存方式,而且还不需要修改ImageLoader类里面的代码,只需要通过调用ImageLoader里面的
上一篇:《面向对象的六大原则之 —— 接口隔离原则》