责任链模式

2019-08-09  本文已影响0人  壮少Bryant

最近做需求,用到了责任链模式,总结一下。

需求场景:播放器记录着所有的播放行为事件PlayBehaviorEvent,业务方根据回传的播放事件,筛选出满足过滤条件的集合(例如播放进度超过30%)。
此时,为了满足不同业务方的过滤条件,需要设计一个通用的方法,需要业务方把过滤条件给播放器,播放器将集合传给业务方,而过滤条件由业务方自定制。

责任链模式,首先每个条件为一个对象,将所有对象结合成一个链表,并沿着这条链传递事件,直到链上的某一个对象决定处理此事件。

话不多说,看代码好理解。

责任链是啥样的?就是找到链表的头结点

public class InterceptorChain {


    private Interceptor mHeader;
    public InterceptorChain() {
    }

    public InterceptorChain add(Interceptor interceptor) {
        if (mHeader == null) {
            mHeader = interceptor;
        } else {
            Interceptor header = mHeader;
            while (header != null) {
                if (header.getNext() == null) {
                    header.next(interceptor);
                    break;
                }
                header = header.getNext();
            }
        }
        return this;
    }

    public Interceptor getHeader() {
        return mHeader;
    }
}

再来看看拦截器啥样

public abstract class Interceptor implements IBehaviorInterceptor {
    private Interceptor nextInterceptor;

    public Interceptor() {
    }

    /**
     *
     * @param interceptor 返回nextInterceptor节点
     * @return
     */
    public Interceptor next(Interceptor interceptor) {
        this.nextInterceptor = interceptor;
        return nextInterceptor;
    }

    public Interceptor getNext() {
        return nextInterceptor;
    }
}

public interface IBehaviorInterceptor {
    boolean intercept(PlayBehaviorEvent event);
}

播放器过滤条件:

public synchronized List<PlayBehaviorEvent> getBehaviorRecord(InterceptorChain interceptor) {
        if (interceptor == null || interceptor.getHeader() == null) {
            // 没有过滤器,就返回了所有事件
            return getAll();
        }
        ArrayList<PlayBehaviorEvent> behaviors = new ArrayList<>();
        Interceptor header;
        boolean isIntercept;
        Map.Entry<String, ArrayList<PlayBehaviorEvent>> entry;
        ArrayList<PlayBehaviorEvent> value;
        //mEvents就是播放器记录的所有的事件
        Iterator<Map.Entry<String, ArrayList<PlayBehaviorEvent>>> entries = mEvents.entrySet().iterator();
        while (entries.hasNext()) {
            entry = entries.next();
            value = entry.getValue();
            // 对每一个事件进行遍历
            for (PlayBehaviorEvent event : value) {
                header = interceptor.getHeader();
                // 默认不拦截
                isIntercept = false;
                // 对所有的拦截条件进行遍历,如果满足所有条件,即都返回false,才能add到返回的集合中
                do {
                    if (header.intercept(event)) {
                        // 如果有一个为true,即有一个条件不满足,就被拦截
                        isIntercept = true;
                        break;
                    }
                    header = header.getNext();
                } while (header != null);

                if (!isIntercept) {
                    behaviors.add(event);
                }
            }
        }
        return behaviors;
    }

看业务方如何获取所有满足条件的集合
拦截链表中有多个拦截方法,必须满足所有条件,才不拦截

List<PlayBehaviorEvent> eventList = playerApi.getBehaviorRecord(new InterceptorChain()
                .add(new Interceptor() {
                    @Override
                    public boolean intercept(PlayBehaviorEvent event) {
                        if (条件1) {
                            // 满足条件1,不拦截
                            return false;
                        }
                        return true;
                    }
                })
                .add(new Interceptor() {
                    @Override
                    public boolean intercept(PlayBehaviorEvent event) {
                        if (条件2) {
                            // 满足条件2,不拦截
                            return false;
                        }
                        return true;
                    }
                }));
上一篇 下一篇

猜你喜欢

热点阅读