责任链模式及实例:模拟图片加载
责任链模式
将很多处理对象连成一条链,并沿着这条链传递请求,直到有对象处理该请求为止。
责任链模式的角色
抽象处理者(Handler)角色
- 定义处理的方法
- 决定链的排列方式
- 设置下一个处理者
具体处理者(ConcreteHandler)角色
- 实现具体的处理
总结:父类实现请求传递的功能,子类实现请求的处理
UML
优点
- 将请求和处理分开
- 请求者无需知道是谁处理
- 处理者无需知道请求的全部
缺点
- 性能问题
- 每一个请求都是从链头到链尾,特别是链比较长的时候
- 调试不方便
注意:
链的节点数量需要控制,避免出现超长链的情况。(可在Handler中设置最大节点数来处理)
实例:模拟图片加载
结合模板方法模式,模拟图片的三级加载 (内存、本地存储及网络)
创建抽象处理者(Handler)
public abstract class ImageHandler {
private ImageHandler nextHandler;
//结合模板方法模式,将共用的抽取出来
public final Bitmap handler() {
Bitmap bitmap = loadBitmap();
if (bitmap != null) {
//如果bitmap!=null,自己处理
return bitmap;
} else {
if (nextHandler != null) {
//让下一个Hanlder处理
return this.nextHandler.handler();
} else {
//没有下一个Handler,返回默认图片
return ImageHelper.loadDefaultBitmap();
}
}
}
public void setNextHandler(ImageHandler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract Bitmap loadBitmap();
}
创建具体处理者(ConcreteHandler)
从内存加载的Handler
public class FromMemoryImageHandler extends ImageHandler {
@Override
public Bitmap loadBitmap() {
return loadBitmapFromMemory();
}
}
从硬盘加载的Handler
public class FromDiskImageHandler extends ImageHandler {
@Override
public Bitmap loadBitmap() {
return loadBitmapFromDisk();
}
}
从网络加载的Handler
public class FromNetImageHandler extends ImageHandler {
@Override
public Bitmap loadBitmap() {
return loadBitmapFromNet();
}
}
组成责任链
public class ImageLoader {
private final FromMemoryImageHandler headHandler;
private final FromDiskImageHandler diskHandler;
private final FromNetImageHandler netHandler;
public ImageLoader() {
headHandler = new FromMemoryImageHandler();
diskHandler = new FromDiskImageHandler();
netHandler = new FromNetImageHandler();
headHandler.setNextHandler(diskHandler);
diskHandler.setNextHandler(netHandler);
}
}
进行异步加载的封装
在之前组成责任链的ImageLoader类的基础上,增加
public class ImageLoader {
private static final int LOAD_BITMAP_SUCCESS = 457;
private static Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case LOAD_BITMAP_SUCCESS:
ImageBox imageBox = (ImageBox) msg.obj;
if (imageBox.bitmap != null && imageBox.imageView != null) {
imageBox.imageView.setImageBitmap(imageBox.bitmap);
}
break;
}
}
};
private final FromMemoryImageHandler headHandler;
private final FromDiskImageHandler diskHandler;
private final FromNetImageHandler netHandler;
public ImageLoader() {
headHandler = new FromMemoryImageHandler();
diskHandler = new FromDiskImageHandler();
netHandler = new FromNetImageHandler();
headHandler.setNextHandler(diskHandler);
diskHandler.setNextHandler(netHandler);
}
public void display(final ImageView imageView) {
//异步加载
new Thread() {
@Override
public void run() {
Bitmap bitmap = headHandler.handler();
Message msg = Message.obtain();
msg.what = LOAD_BITMAP_SUCCESS;
msg.obj = new ImageBox(bitmap, imageView);
mHandler.sendMessage(msg);
}
}.start();
}
private class ImageBox {
public ImageBox(Bitmap bitmap, ImageView imageView) {
this.bitmap = bitmap;
this.imageView = imageView;
}
Bitmap bitmap;
ImageView imageView;
}
}
Client中调用
imageLoader.display(imageView);
我们可以看到,Client中,只需发起一个请求,最终会返回解决。无需知道请求是谁处理的,屏蔽了请求的处理过程。
同时,责任链模式也可作为一种补救模式
可在很方便的在原来单一的处理类上使用责任链模式,进行扩展,从而满足新业务的需要。
参考
《设计模式之禅第二版》