正巧这一章讲的就是图片加载器,和我的项目类似,于是我就读了这一章的内容。
首先Android开发涉及Java语言,程序中的抽象、接口、六大原则、23种设计模式等名词,这一些就像书中的小民,我已经晕头转向。
ImageCache.java
public class ImageLoader{
ImageCache mImageCache=new ImageChache();
ExecutorService mExecutorService=executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
public void displayImage(final String url,final ImageView imageView){
Bitmap bitmap=ImageCache.get(url);
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);
}
mImageCache.put(url,bitmap);
}
});
public 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;
}
}
public class ImageCache{
LruCache mImageCache;
public ImageCache(){
initImageCache();
}
private void initImageCache(){
final int maxMemory=(int)(Runtime.getRuntime().maxMemory()/1024);
final int cacheSize=maxMemory/4;
mImageCache=new LruCache(cacheSize){
@Override
protected int sizeOf(String key,Bitmap bitmap){
return bitmap.getRowBytes()*bitmap.getHeight()/1024;
}
};
}
public void put(String url,Bitmap bitmap){
mImageCache.put(url,bitmap);
}
public Bitmap get(String url){
return mImageCache.get(url);
}
}
应用的是单一模式,让ImageLoader一拆为二,ImageLoader只负责图片加速的逻辑,而ImageCache只负责处理图片换春的逻辑。这样ImageLoader的代码量就变少了。
首先写一个双缓存类DoubleCache,具体代码如下:
public class DoubleCache {
ImageCache mMemoryCache=new ImageCache();
DiskCache 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 bmp){
mMemoryCache.put(url,bmp);
mDiskCache.put(url,bmp);
}
}
然后是最新的ImageLoader:
public class ImageLoader{
ImageCache mIamgeCache=new IamgeCache();
DiskCache mDiskCache=new DiskCache();
DoubleCache mDoubleCache=newDoubleCache();
boolean isUseDiskCache=false;
boolean isUseDoubleCache=false;
ExecutorService mExecutorService=executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
public void displayImage(final String url,final ImageView imageView){
Bitmap bitmap=null;
if(isUseDoubleCache){
bmp=mDoubleCache.get(url);
}else if(isUseDiskCache){
bmp=mDiskCache.get(url);
}else{
bmp=mImageCache.get(url);
}
if(bmp!=null) {
imageView.setImageBitmap(bmp);
}
}
public void useDiskCache(boolean useDiskCache){
isUseDiskCache=useDiskcache;
}
public void useDoubleCache(boolean useDoubleCache){
isUseDoubleCache=useDoubleCache;
}
}
于是便提出了下面的UML图:
于是便将ImageLoader类重构:
public class ImageLoader{
ImageCache mIamgeCache=new IamgeCache();
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,fianl 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);
}
}
});
}
public Bitmap downloadImage(String imageUrl){
Bitmap bitmap=null;
try{
URL url=new URL(imageUrl);
final HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.discount();
}catch(Exception e){
e.printStackTrace();
}
return bitmap;
}
}
public interface ImageCache{
public void put(String url,Bitmap bitmap);
public Bitmap get(String url);
}
软件需要变化时,需要通过扩展的方式来实现变化,而不是反复的修改。“应该尽量”,OCP原则并不是绝对不可以修改原始类的。当原有的代码完全不适合扩展时,应该尽早地重构,以便使代码恢复到正常的”进化“过程。
里氏替换原则
Liskov Substitution Principle
示例代码:
public class Windows {
public void show(View child){
child.show();
}
}
public abstract class View{
public abstract void draw();
public void measure(int width,int height){
//测量视图大小
}
}
publlic class Button extends View{
public void draw(){
//绘制按钮
}
}
public class TextView extends View{
public void draw(){
//绘制文本
}
}
单一职责 开闭原则 里氏替换原则 接口隔离 依赖倒置(依赖反转)定义为SOLID原则。
Law of Demeter
最少知识原则