责任链模式分享

责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

●  抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
●  具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
 
package me.duzhi.blog.hok;

import java.lang.annotation.*;

/**
 * 权重定义以及Annotion
 * @author ashang.peng@aliyun.com
 * @date 二月 14, 2017
 */
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Hok {

    public static final int DEFAULT_WEIGHT = 10;
    /**
     * 操作
     */
    String[] action();

    int weight() default DEFAULT_WEIGHT;
}

定义一个Annotation 标志此为一个Hok;

定义一个基础处理类,供真正的Action 继承;

package me.duzhi.blog.hok;

/**
 * 基础处理类
 * @author ashang.peng@aliyun.com
 * @date 二月 14, 2017
 */

public abstract class Action {
    /**
     * The next handler
     */
    protected Action next;


    public abstract <T> void handle(HokInvoke.Message message, HokInvoke.Inv<T> invoke, String action);

    public <T extends Action> T addAction(Class<T> actionClass ) throws IllegalAccessException, InstantiationException {
        this.next = actionClass.newInstance();
        return (T) next;
    }
}

 

增加一个管理类,供别人使用,

1、搜索工程中的带有hok标签的对象以及操作

2、增加注册方法供大家注册。

3、权重函数大家应该都明白,无非排序;

package me.duzhi.blog.hok;

import com.jfinal.log.Log;
import io.jpress.utils.ClassUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ashang.peng@aliyun.com
 * @date 二月 14, 2017
 */

public class HokManager {
    private final Map<String, List<Action>> actionMap;
    public static HokManager me = new HokManager();
    private static final Log log = Log.getLog(HokManager.class);

    public HokManager() {
        actionMap = new ConcurrentHashMap<String, List<Action>>();
    }
    public boolean init = false;
    public static HokManager me() {
        if(!me.init) {
            synchronized (me) {
                if(!me.init) {
                    me.init= true;
                    me.init();
                }
            }
        }
        return me;
    }

    public void registerAction(Class<? extends Action> actionClass) {
        if (actionClass == null) {
            return;
        }
        Hok listenerAnnotation = actionClass.getAnnotation(Hok.class);
        if (listenerAnnotation == null) {
            log.warn("actionClass[" + listenerAnnotation + "] resigter fail,because not use Hok annotation.");
            return;
        }
        String[] actions = listenerAnnotation.action();
        for (String action : actions) {
            List<Action> actions1 = actionMap.get(action);
            if (actions1 == null) {
                actions1 = new ArrayList<Action>();
            }
            Action action1 = newAction(actionClass);
            actions1.add(action1);
            Collections.sort(actions1, new Comparator<Action>() {
                @Override
                public int compare(Action o1, Action o2) {
                    Hok l1 = o1.getClass().getAnnotation(Hok.class);
                    Hok l2 = o2.getClass().getAnnotation(Hok.class);
                    return l1.weight() - l2.weight();
                }
            });
            actionMap.put(action, actions1);
        }
    }

    public void unRegisterAction(Class<? extends Action> actionClass) {
        for (Map.Entry<String, List<Action>> entry : actionMap.entrySet()) {
            Action deleteAction = null;
            for (Action action : entry.getValue()) {
                if (action.getClass() == actionClass) {
                    deleteAction = action;
                }
            }
            if (deleteAction != null) {
                entry.getValue().remove(deleteAction);
            }
        }
    }

    private Action newAction(Class<? extends Action> actionClass) {
        Action action = null;
        try {
            action = actionClass.newInstance();
        } catch (Throwable e) {
            log.error(String.format("action \"%s\" newInstance is error. ", actionClass), e);
        }
        return action;
    }

    /**
     * @param action
     * @param invoke
     * @param <T>
     * @return
     */
    public <T> void invoke(HokInvoke.Message message, HokInvoke.Inv<T> invoke, String action) {
        List<Action> actions = actionMap.get(action);
        Action action1 = getHandler(actions, new DefaultAction());
        action1.handle(message, invoke, action);
    }

    public void init() {
        List<Class<Action>> list = ClassUtils.scanSubClass(Action.class,true);
        for (Class<Action> actionClass : list) {
            Hok hok = actionClass.getAnnotation(Hok.class);
            if (hok != null) {
                HokManager.me().registerAction(actionClass);
            }
        }
    }

    public static Action getHandler(List<Action> handlerList, Action action) {
        Action result = action;
        if (handlerList != null) {
            for (int i = handlerList.size() - 1; i >= 0; i--) {
                Action temp = handlerList.get(i);
                temp.next = result;
                result = temp;
            }
        }
        return result;
    }
}

 

通过Init action 初始化下一个Hanlder对象,有下一个继续给下一个,不断继续下去。

 

 

除特别注明外,本站所有文章均为duzhi原创,转载请注明出处来自https://www.duzhi.me/article/1817.html

联系我们

******

在线咨询:点击这里给我发消息

邮件:ashang.peng#aliyun.com

QR code