责任链模式及实例: 模拟图片加载

责任链模式及实例:模拟图片加载

 责任链模式

将很多处理对象连成一条链,并沿着这条链传递请求,直到有对象处理该请求为止。

责任链模式的角色

  • 抽象处理者(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中,只需发起一个请求,最终会返回解决。无需知道请求是谁处理的,屏蔽了请求的处理过程。

同时,责任链模式也可作为一种补救模式

可在很方便的在原来单一的处理类上使用责任链模式,进行扩展,从而满足新业务的需要。

参考
《设计模式之禅第二版》

相关源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

氦客

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值