责任链模式

责任链模式属于行为类模式,其意图是将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

责任链的核心在“链”上,“链”是由多个处理者组成的,“链”上的处理者负责处理请求,客户只需将请求发送到“链”上即可,无需关心请求的处理细节和请求的传递方向。这样请求的发送者和请求的处理者实现了解耦。

 

示例

定义一个业务场景,DNS协议“规定”每个区域的DNS服务器(Local DNS)只保留自己区域的域名解析,对于不能解析的域名,则提交上级域名解析器解析,最终由一台位于美国洛杉矶的顶级域名服务器进行解析,返回结果。三个DNS服务器分别为:上海DNS服务器(区域服务器)、中国顶级DNS服务器(父服务器)、全球顶级DNS服务器。DNS解析示意图如下:

示例类图如下:


 

/**
 * 解析记录POJO
 * @author wei.jiang
 * @since 2016-09-21
 */
public class Recorder {
    /**域名**/
    private String domain;
    /**IP**/
    private String ip;
    /**属主**/
    private String owner;

    public String getDomain() {
        return domain;
    }
    public void setDomain(String domain) {
        this.domain = domain;
    }
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public String getOwner() {
        return owner;
    }
    public void setOwner(String owner) {
        this.owner = owner;
    }

    @Override
    public String toString() {
        return domain+"由"+owner+", 解析后的IP为"+ip;
    }
}

 

/**
 * DnsServer抽象类
 * @author wei.jiang
 * @since 2016-09-21
 */
public abstract class DnsServer {
    //上级DnsServer
    private DnsServer upperServer;

    /**
     * 解析域名
     * @param domain
     * @return
     */
    public final Recorder resolve(String domain){
        Recorder recorder = null;
        if(this.isLocal(domain)){//本级能解析的域名
            recorder = echo(domain);
        }else{//本级不能解析的域名,提交上级解析
            recorder = this.upperServer.resolve(domain);
        }
        return recorder;
    }

    /**
     * 指向上级DNS
     * @param upperServer
     */
    public void setUpperServer(DnsServer upperServer){
        this.upperServer = upperServer;
    }

    //本级能否解析该域名
    protected abstract boolean isLocal(String domain);

    /**
     * 每个DNS服务器必须实现解析任务
     * @param domain
     * @return
     */
    protected Recorder echo(String domain){
        Recorder recorder = new Recorder();
        recorder.setDomain(domain);
        recorder.setIp(getIp());
        return recorder;
    }

    /**
     * 随机生成一个IP地址
     * @return
     */
    private String getIp(){
        Random random = new Random();
        return random.nextInt(255)+"."+random.nextInt(255)
            +"."+random.nextInt(255)+"."+random.nextInt(255);
    }
}

 

/**
 * 上海DnsServer实现类
 * @author wei.jiang
 * @since 2016-09-21
 */
public class SHDnsServer extends DnsServer {

    /**
     * 定义上海DNS能够处理的级别
     */
    @Override
    protected boolean isLocal(String domain) {
        return domain.endsWith(".sh.cn");
    }

    protected Recorder echo(String domain){
        Recorder recorder = super.echo(domain);
        recorder.setOwner("上海DNS服务器解析");
        return recorder;
    }
}

 

/**
 * 中国顶级DnsServer实现类
 * @author wei.jiang
 * @since 2016-09-21
 */
public class ChinaDnsServer extends DnsServer{

    /**
     * 定义中国顶级DNS能够处理的级别
     */
    @Override
    protected boolean isLocal(String domain) {
        return domain.endsWith(".cn");
    }

    protected Recorder echo(String domain){
        Recorder recorder = super.echo(domain);
        recorder.setOwner("中国DNS服务器解析");
        return recorder;
    }
}

 

/**
 * 全球顶级DnsServer实现类
 * @author wei.jiang
 * @since 2016-09-21
 */
public class TopDnsServer extends DnsServer {

    @Override
    protected boolean isLocal(String domain) {
        return true;
    }

    protected Recorder echo(String domain){
        Recorder recorder = super.echo(domain);
        recorder.setOwner("顶级DNS服务器解析");
        return recorder;
    }
}

 

/**
 * 场景类
 * @author wei.jiang
 * @since 2016-09-21
 */
public class Client {
    public static void main(String[] args) throws IOException {
        //上海域名服务器
        DnsServer sHDnsServer = new SHDnsServer();
        //中国顶级域名服务器
        DnsServer chinaDnsServer = new ChinaDnsServer();
        //全球顶级域名服务器
        DnsServer topDnsServer = new TopDnsServer();
        //定义查询路径
        sHDnsServer.setUpperServer(chinaDnsServer);
        chinaDnsServer.setUpperServer(topDnsServer);

        System.out.println("-------域名解析模拟器------");
        while(true){
            System.out.println("请输入域名(输入N退出):");
            String domain = (new BufferedReader(new InputStreamReader(System.in))).readLine();
            if(domain != null && !"".equals(domain)){
                if(domain.equalsIgnoreCase("N")){
                    return;
                }
                Recorder recorder = sHDnsServer.resolve(domain);
                System.out.println(recorder.toString());
            }else{
                System.out.println("请输入域名:(输入N退出):");
            }
        }
    }
}

 

输出结果:
-------域名解析模拟器------
请输入域名(输入N退出):
www.baidu.sh.cn
www.baidu.sh.cn由上海DNS服务器解析, 解析后的IP为234.135.13.216
请输入域名(输入N退出):
www.baidu.cn
www.baidu.cn由中国DNS服务器解析, 解析后的IP为110.237.58.78
请输入域名(输入N退出):
www.baidu.com
www.baidu.com由顶级DNS服务器解析, 解析后的IP为131.55.162.121
请输入域名(输入N退出):
N

责任链模式通用类图
这里写图片描述

Handler:抽象处理者,需实现三个职责

  1. 定义一个请求的处理方法
  2. 定义一个链路的编排方法
  3. 定义自己能够处理的级别和具体的处理任务

抽象处理者通用代码:

/**
* 抽象处理者
* @author wei.jiang
* @since 2016-09-21
*/
public abstract class Handler {

private Handler nextHandler;

/**
 * 处理请求
 * @param request
 * @return
 */
public final Response handleMessage(Request request){
    Response response = null;
    if(this){

    }else{

    }
}

}

ConcreteHandler:具体的处理者

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值