设计模式-责任链模式

摘要:

  责任链设计模式说白了就是一个个的过滤器的使用,打个比方就好比水净化器一样,一层一层的处理直到最后其实责任链模式就是这样的没什么特别的下面来详细看看!

一、责任链模式定义

1、定义

 是一个请求有多个对象来处理,这些对象是一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链中的下一个对象,直到链执行完为止。

2、类图

没有统一实现方式,所以这里就不展示类图……

二、使用场景

 1、有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定。

 2、在不明确指定接受者的情况下,向多个对象中的一个提交一个请求。

 3、可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求。

三、代码示例

首先看看链的基本组成,写链的目的是为了处理具体的问题,所以这里我们就写一个过滤链来学习一下

1、链中的过滤者,也就是具体过滤功能实现类

2、链类,链类的功能就是遍历执行所有的链中的过滤者以及最后返回值。

3、链工厂类,这个类的主要功能就是链中添加过滤类并触发链中的过滤方法开始走链中的过滤方法……

下面来看看实现代码

1、过滤接口

过滤接口的方法中有两个参数应该是必须的第一要处理的请求参数(返回参数),第二过滤链

public interface DriverFilter {

    /**
     * 条件过滤
     * @param filterDriverParam
     * @param chain
     */
    void filter(FilterDriverParam filterDriverParam, FilterDriverChain chain);

}

2、默认的过滤类实现了过滤接口

过滤类中做了具体的过滤操作,比如这个类中引入了一个service来做具体的过滤操作……

@Service("defaultDriverFilter")

public class DefaultDriverFilter implements DriverFilter {
    @Autowired
    private FilterDriverService filterDriverService;
    @Override
    public void filter(FilterDriverParam filterDriverParam, FilterDriverChain chain) {
        filterDriverService.filterDriver(filterDriverParam);
        chain.doFilter(filterDriverParam);
    }
}

3、过滤链

public interface FilterDriverChain {

    /**
     * 过滤司机
     *
     * @param filterDriverParam
     */

    List<DriverMongo> doFilter(FilterDriverParam filterDriverParam);

    /**
     * 添加过滤器
     *
     * @param filter
     */
    void addFilter(DriverFilter filter);
}

4、默认过滤链类

过滤链类中有个过滤方法即doFilter方法,这个方法中遍历所有的链中的过滤类进行过滤直到链走完才返回结果

public class DefaultFilterDriverChain implements FilterDriverChain {
    private List<DriverFilter> filters = new ArrayList<>(16);
    int index = 0;
    @Override
    public List<DriverMongo> doFilter(FilterDriverParam filterDriverParam) {

        if (index >= filters.size()) {
            return filterDriverParam.getDriverMongoList();
        }

        filters.get(index++).filter(filterDriverParam, this);
        return filterDriverParam.getDriverMongoList();
    }

    @Override
    public void addFilter(DriverFilter filter) {
        this.filters.add(filter);
    }
}

5、过滤链工厂类

这个工厂类中做了两件事第一将过滤类添加到过滤链中 第二触发过滤链中的方法开始执行过滤

public class FilterDriverChainFactory {
    private static Logger LOG = LoggerFactory.getLogger(FilterDriverChainFactory.class);
    private static Map<String, DriverFilter> FILTER_MAP;
    static {
        Map<String, DriverFilter> map = com.ichinait.core.util.SpringBeanUtil.beansOfTypeIncludingAncestors(DriverFilter.class);

        FILTER_MAP = new HashMap<>(map.size());
        Iterator<Map.Entry<String, DriverFilter>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            DriverFilter filter = iterator.next().getValue();
            FILTER_MAP.put(filter.getClass().getName(), filter);
        }
    }

    public static List<DriverMongo> filter(FilterDriverParam filterDriverParam) {
       
        DefaultFilterDriverChain chain = new DefaultFilterDriverChain();

        addFilter(chain, DefaultDriverFilter.class);

        return chain.doFilter(filterDriverParam);

    }


    private static void addFilter(FilterDriverChain chain, Class<? extends DriverFilter> type) {

        chain.addFilter(doGetFilter(type));
    }

    private static DriverFilter doGetFilter(Class<? extends DriverFilter> type) {

        return FILTER_MAP.get(type.getName());
    }

}

6、获取实现过滤接口的实现类的实例工具类

public class SpringBeanUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringBeanUtil.applicationContext = applicationContext;
    }

    public static Object getBeanByName(String beanName) {
        if (null == applicationContext) {
            return null;
        }

        return applicationContext.getBean(beanName);
    }

    public static <T> T getBean(Class<T> type) {

        return applicationContext.getBean(type);
    }
    public static <T> Map<String, T> beansOfTypeIncludingAncestors(Class<T> type) {
        return BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, type, false, false);
    }
}

四、断链问题解决

这个责任链存在断开的问题,在具体的处理类中如果忘记chain.filter则链就此断开了……所以我们要修改一下

1、链接口定义

public interface DriverFilter {

    /**
     * 条件过滤
     * @param filterDriverParam
     * @param chain
     */

    void filter(FilterDriverParam filterDriverParam, FilterDriverChain chain);

  /**
     * 条件过滤(执行具体过滤)
     * @param filterDriverParam
     * @param chain
     */
    void doFilter(FilterDriverParam filterDriverParam, FilterDriverChain chain);
}

2、过滤抽象列实现filter方法

/**
* 抽象类中实现链连接方法
*/
public abstract class AbstractDriverFilter implements DriverFilter{
    /**
     * 防止断链
     * @param filterDriverParam
     * @param chain
     */
    void filter(FilterDriverParam filterDriverParam, FilterDriverChain chain){
        doFilter(filterDriverParam,chain);
        chain.doFilter(filterDriverParam);
    }
}

3、实现抽象类

/**
* 具体过滤类
*/
public class DistanceDriverFilter extends AbstractDriverFilter {
    @Override
    public void doFilter(FilterDriverParam filterDriverParam) {
        // 业务处理
    }
}

五、知识点扩展

责任链模式,主要在链上,只要我们在执行具体的业务逻辑前能把链执行完就可以,所以各种实现方式都有。

1、上面这种实现方式在servlet 中使用

2、dubbo 的链实现方式如下:

private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
    Invoker<T> last = invoker;
    //filter获取
    List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
    if (filters.size() > 0) {
        //倒序遍历
        for (int i = filters.size() - 1; i >= 0; i --) {
            final Filter filter = filters.get(i);
            final Invoker<T> next = last;
            //匿名类生成一个Invoker对象,并将形参invoker设置为链表中的最后一个
            last = new Invoker<T>() {
                public Class<T> getInterface() {
                    return invoker.getInterface();
                }
                public URL getUrl() {
                    return invoker.getUrl();
                }

                public boolean isAvailable() {
                    return invoker.isAvailable();
                }

                public Result invoke(Invocation invocation) throws RpcException {
                    return filter.invoke(next, invocation);
                }

                public void destroy() {
                    invoker.destroy();
                }

                @Override
                public String toString() {
                    return invoker.toString();
                }
            };
        }

    }

    //遍历结束生成了一个filter1->filter2->filter3……->filterlast->invoker这样的链表并把filter1返回
    return last;
}


 

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值