`
不平凡的人
  • 浏览: 35495 次
  • 性别: Icon_minigender_1
  • 来自: 嘉峪关
社区版块
存档分类
最新评论

责任链模式

 
阅读更多

本文从以下几个示例介绍责任链模型

 

一、概念

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

 

二、示例展示

 

1、简单示例引入

 

(1)示例介绍:模拟客户端向服务端发送消息时校验问题,比如说我们发送给服务端的消息要进行敏感词,脚本信息的过滤等处理,特殊情况处理之后将消息发送给服务器。

(2)代码示例

package net.oschina.design.chainofresponsibility.example;

/**
 * 一个简单的例子引出责任链模式 消息处理类
 * 
 * @author Freedom
 * 
 */
public class MsgProcess {

	private String msg;

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	/**
	 * 消息处理程序 客户端-->到服务端的消息进行一个过滤 过滤敏感字符,过滤脚本等信息
	 * 
	 * @param msg
	 * @return
	 */
	public String doFilter() {

		// 最简单 的做饭直接在该方法中进行处理
		// 1. 处理脚本 <> --> []
		String r = msg;
		r = r.replace("<", "[").replace(">", "]");
		// 处理敏感字符
		r = r.replace("潜规则", "***").replace("SB", "***");

		// 引发思考,如果说程序中又多了很多种对字符串过滤规则,则每次都要修改这个类中的方法不便于扩展
		// 想法:找出需求中的变化部分,因为过滤规则可以有多重,因此将过滤规则抽象为接口,加其实现这样就方法便扩展了

		return r;
	}
}
package net.oschina.design.chainofresponsibility.example;

/**
 * 测试方法
 * 
 * @author Freedom
 * 
 */
public class Main {

	public static void main(String[] args) {

		String msg = "xxx被潜规则<script>,真的很SB,且行且珍惜";
		MsgProcess mp = new MsgProcess();
		mp.setMsg(msg);
		System.out.println(mp.doFilter());
	}

}

①示例引发的思考

       通过上述示例可以看出,如果说,对客户端发送的消息过滤的规则修改了或者是新增了一些过滤规则,每次 都要修改该类中方法,明显违背了开发关闭原则;

②解决方案

       通过上述示例,明确得出变化的部分是消息的校验规则不同,因此可以将消息的校验规则抽象出一个接口,然后子类实现该接口形成一个行为族,看如下示例。

 

2、过滤规则抽象为接口及子类实现的方式

2.1、代码示例

2.1.1 过滤规则的接口

package net.oschina.design.chainofresponsibility.simplefilter.filterinterface;

/**
 * 处理客户端消息的过滤器接口 后续如果有多重过滤规则,只需要实现该接口,重写方法即可
 * 
 * @author Freedom
 * 
 */
public interface Filter {

	/**
	 * 过滤消息
	 * 
	 * @param msg
	 * @return
	 */
	String doFilter(String msg);
}

 2.1.2 过滤规则的实现类

package net.oschina.design.chainofresponsibility.simplefilter.filterinterface.impl;

import net.oschina.design.chainofresponsibility.simplefilter.filterinterface.Filter;

/**
 * 处理脚本的过滤器
 * 
 * @author Freedom
 * 
 */
public class ScriptFilter implements Filter {

	@Override
	public String doFilter(String msg) {
		String r = msg;
		r = r.replace("<", "[").replace(">", "]");
		return r;
	}

}

 

package net.oschina.design.chainofresponsibility.simplefilter.filterinterface.impl;

import net.oschina.design.chainofresponsibility.simplefilter.filterinterface.Filter;

/**
 * 处理敏感词的过滤器
 * 
 * @author Freedom
 * 
 */
public class SensitiveFilter implements Filter {

	@Override
	public String doFilter(String msg) {
		String r = msg;
		r = r.replace("潜规则", "***").replace("SB", "***");
		return r;
	}

}

 

2.1.3 消息处理程序类

package net.oschina.design.chainofresponsibility.simplefilter;

import net.oschina.design.chainofresponsibility.simplefilter.filterinterface.Filter;
import net.oschina.design.chainofresponsibility.simplefilter.filterinterface.impl.ScriptFilter;
import net.oschina.design.chainofresponsibility.simplefilter.filterinterface.impl.SensitiveFilter;

/**
 * 一个简单的例子引出责任链模式 消息处理类
 * 
 * @author Freedom
 * 
 */
public class MsgProcess {

	private String msg;

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	// 获取过滤器并保存
	// 如果后续有新增加的过滤器,只需要在数据里面添加即可
	// 此方式可以改变过滤顺序,只需改变数据中元素存放位置即可
	Filter[] filters = { new ScriptFilter(), new SensitiveFilter() };

	/**
	 * 消息处理程序 客户端-->到服务端的消息进行一个过滤 过滤敏感字符,过滤脚本等信息 思考:
	 * 上述方式只是一条过滤规则,如果我们添加了一条过滤规则,并且该规则中有多个简单的过滤规则,如何实现?
	 * 
	 * @param msg
	 * @return
	 */
	public String processMsg() {
		String r = msg;
		for (Filter f : filters) {
			r = f.doFilter(r);
		}

		return r;
	}
}

 该类的实现中 processMsg()方法,只需要之前的实现的过滤规则的子类作为一个集合对象组合到该类中即可。遍历集合中过滤规则子类然后调用各自的过滤方法。

 

2.2 、示例思考

(1)上述示例可以看出,如果程序中需要新增过滤规则,只需要实现Filter接口即可。但是,方法中只是展示了一条过滤规则链,如果说有程序中又新增了一条过滤规则链而且该过滤规则链中同样也是有多了个过滤规则对象组成,又该如何实现?

(2)分析上述变化:其实解决思路可以将新增的过滤规则链看成一个整体,该整体的无外乎也是对消息的过滤,因此新增的过滤规则链(整体对象)其实也是一个Filter对象。请看如下示例。

 

3、程序中有多条过滤规则链的实现

3.1、代码示例

3.1.1、过滤规则接口及其实现类

package net.oschina.design.chainofresponsibility.manyfilter.filterinterface;

/**
 * 处理客户端消息的过滤器接口 后续如果有多重过滤规则,只需要实现该接口,重写方法即可
 * 
 * @author Freedom
 * 
 */
public interface Filter {

	/**
	 * 过滤消息
	 * 
	 * @param msg
	 * @return
	 */
	String doFilter(String msg);
}

package net.oschina.design.chainofresponsibility.manyfilter.filterinterface.impl;

import net.oschina.design.chainofresponsibility.manyfilter.filterinterface.Filter;

/**
 * 处理脚本的过滤器
 * 
 * @author Freedom
 * 
 */
public class ScriptFilter implements Filter {

	@Override
	public String doFilter(String msg) {
		String r = msg;
		r = r.replace("<", "[").replace(">", "]");
		return r;
	}

}

package net.oschina.design.chainofresponsibility.manyfilter.filterinterface.impl;

import net.oschina.design.chainofresponsibility.manyfilter.filterinterface.Filter;

/**
 * 处理敏感词的过滤器
 * 
 * @author Freedom
 * 
 */
public class SensitiveFilter implements Filter {

	@Override
	public String doFilter(String msg) {
		String r = msg;
		r = r.replace("潜规则", "***").replace("SB", "***");
		return r;
	}

}

 3.1.2、新增过滤规则链的实现类

package net.oschina.design.chainofresponsibility.manyfilter;

import java.util.ArrayList;
import java.util.List;

import net.oschina.design.chainofresponsibility.manyfilter.filterinterface.Filter;

/**
 * 过滤器链 目的:处理当多了一条链式规则时(该过滤链中有多条简单过滤规则)方式 想法:将该过滤链看成一个整体,其实质也就是一个过滤规则
 * 为了将该过滤规则链加入其他过滤规则链中,因此该类要实现Filter接口 简单讲:就是将多个过滤器对象组成的过滤规则链看成一个整体,该整体也是一个过滤规则
 * 
 * @author Freedom
 * 
 */
public class FilterChain implements Filter {

	// 保存过滤器对象的链表
	private List<Filter> filters = null;

	public List<Filter> getFilters() {
		return filters;
	}

	public void setFilters(List<Filter> filters) {
		this.filters = filters;
	}

	public FilterChain() {
		filters = new ArrayList<Filter>();
	}

	// 添加过滤器对象
	// 该方法返回对象本身的目的是为了,能够链式的调用方法 ,如:this.addFilter(f).addFilter(f)...
	public Filter addFilter(Filter f) {
		if (!filters.contains(f)) {
			filters.add(f);
		}
		return this;
	}

	@Override
	public String doFilter(String msg) {
		String r = msg;
		for (Filter f : filters) {
			r = f.doFilter(r);
		}

		return r;
	}

}

 

3.1.3、处理消息的程序类

package net.oschina.design.chainofresponsibility.manyfilter;

import java.util.List;

import net.oschina.design.chainofresponsibility.manyfilter.filterinterface.Filter;

/**
 * 一个简单的例子引出责任链模式 消息处理类
 * 
 * @author Freedom
 * 
 */
public class MsgProcess {

	private String msg;

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	// 过滤规则链
	// 简单期间就不用链表结构了
	private FilterChain chain;

	public FilterChain getChain() {
		return chain;
	}

	public void setChain(FilterChain chain) {
		this.chain = chain;
	}

	public MsgProcess(FilterChain chain) {
		this.chain = chain;
	}

	/**
	 * 消息处理程序 客户端-->到服务端的消息进行一个过滤 过滤敏感字符,过滤脚本等信息 思考:
	 * 上述方式只是一条过滤规则,如果我们添加了一条过滤规则,并且该规则中有多个简单的过滤规则,如何实现?
	 * 
	 * @param msg
	 * @return
	 */
	public String processMsg() {
		String r = msg;

		// 获取过滤规则链中过滤规则对象
		List<Filter> filters = chain.getFilters();

		for (Filter f : filters) {
			r = f.doFilter(r);
		}

		return r;
	}
}

 主函数:

package net.oschina.design.chainofresponsibility.manyfilter;

import net.oschina.design.chainofresponsibility.manyfilter.filterinterface.impl.ScriptFilter;
import net.oschina.design.chainofresponsibility.manyfilter.filterinterface.impl.SensitiveFilter;

/**
 * 测试方法 思考:目前的情况只是针对客户端到服务端消息的过滤
 * 如果说服务端到客户端的消息同样也要实现过滤,并且客户端到服务端过滤规则结束时,服务端到客户端校验规则开始(校验规则倒序)要如何实现?
 * 
 * @author Freedom
 * 
 */
public class Main {

	public static void main(String[] args) {

		String msg = "xxx被潜规则<script>,真的很SB,且行且珍惜";

		// 第一条过滤规则链
		FilterChain chain = new FilterChain();
		chain.addFilter(new ScriptFilter());
		chain.addFilter(new SensitiveFilter());

		// 第二条过滤规则链
		FilterChain chain1 = new FilterChain();
		chain1.addFilter(new ScriptFilter());

		// 将第二条过滤规则链添加到第一条过滤规则链中
		chain.addFilter(chain1);

		MsgProcess mp = new MsgProcess(chain);
		mp.setMsg(msg);
		System.out.println(mp.processMsg());
	}

}

 

3.2、对示例的思考

(1)之前的示例展示的都是对客户端发送消息到服务端的处理。同样服务端响应消息到客户端同样也要进行处理并且处理的过滤规则顺序与之前客户端到服务端的处理规则顺序相反,又该如何实现呢?

(2)问题分析:无论是客户端发消息到服务端,还是服务端响应消息到客户端,其实质都是对消息的过滤,这时我们只需要将两者发送的消息封装到对象中,然后对各自对象中消息进行处理。关于过滤规则逆序处理方式,我们只需将过滤规则链对象出入接口方法中,在方法的实现上加上计数器,每当请求消息处理完成后不立即处理相同过滤规则的响应消息,而是处理下一种过滤规则的请求消息,依次类推。请看如下示例。

 

4、同时处理请求以及响应消息的过滤

4.1、代码示例

4.1.1、过滤接口以及其实现类

package net.oschina.design.chainofresponsibility.finalfilter;

/**
 * 
 * 处理客户端到服务端的消息的过滤,同时也处理服务端到客户端消息的过滤
 * 
 * 为了实现 服务端 到客户端消息处理时,过滤规则倒序的情况要将FilterChain对象传入到方法中
 * 
 * @author Freedom
 * 
 */
public interface Filter {

	/**
	 * 过滤消息 该情况不能实现服务端到客户端消息过滤时,过滤规则的倒序
	 * 
	 * @param msg
	 * @return
	 */
	// void doFilter(Request req, Response resp);

	/**
	 * 要将FilterChain传入方法中实现服务端--》客户端过滤规则倒序
	 */
	void doFilter(Request req, Response resp, FilterChain chain);
}

package net.oschina.design.chainofresponsibility.finalfilter;

/**
 * 处理脚本的过滤器
 * 
 * @author Freedom
 * 
 */
public class ScriptFilter implements Filter {

	@Override
	public void doFilter(Request req, Response resp, FilterChain chain) {
		// 处理请求消息的过滤
		String reqMsg = req.reqMsg;
		reqMsg = reqMsg.replace("<", "[").replace(">", "]")
				+ "----scriptFilter";
		System.out.println(reqMsg);

		// 处理服务器端响应消息之前先处理所有客户端消息的过滤
		chain.doFilter(req, resp, chain);

		// 处理响应消息的过滤
		String respMsg = resp.respMsg;
		System.out.println(respMsg + "  --response scriptFilter");
	}

	// @Override
	// public void doFilter(Request req, Response resp) {
	// // 处理请求消息的过滤
	// String reqMsg = req.reqMsg;
	// reqMsg = reqMsg.replace("<", "[").replace(">", "]")
	// + "----scriptFilter";
	// System.out.println(reqMsg);
	//
	// // 处理响应消息的过滤
	// String respMsg = resp.respMsg;
	// System.out.println(respMsg + "  --response scriptFilter");
	// }

}

package net.oschina.design.chainofresponsibility.finalfilter;

/**
 * 处理敏感词的过滤器
 * 
 * @author Freedom
 * 
 */
public class SensitiveFilter implements Filter {

	@Override
	public void doFilter(Request req, Response resp, FilterChain chain) {
		String reqMsg = req.reqMsg;
		reqMsg = reqMsg.replace("潜规则", "***").replace("SB", "***")
				+ "----SensitiveFilter";
		System.out.println(reqMsg);

		chain.doFilter(req, resp, chain);

		// 处理响应消息的过滤
		String respMsg = resp.respMsg;
		System.out.println(respMsg + "  --response SensitiveFilter");
	}

	// @Override
	// public void doFilter(Request req, Response resp) {
	// // 处理请求消息的过滤
	// String reqMsg = req.reqMsg;
	// reqMsg = reqMsg.replace("潜规则", "***").replace("SB", "***")
	// + "----SensitiveFilter";
	// System.out.println(reqMsg);
	//
	// // 处理响应消息的过滤
	// String respMsg = resp.respMsg;
	// System.out.println(respMsg + "  --response SensitiveFilter");
	//
	// }

}

 

4.1.2、过滤规则链类

package net.oschina.design.chainofresponsibility.finalfilter;

import java.util.ArrayList;
import java.util.List;

/**
 * 过滤器链 目的:处理当多了一条链式规则时(该过滤链中有多条简单过滤规则)方式 想法:将该过滤链看成一个整体,其实质也就是一个过滤规则
 * 为了将该过滤规则链加入其他过滤规则链中,因此该类要实现Filter接口 简单讲:就是将多个过滤器对象组成的过滤规则链看成一个整体,该整体也是一个过滤规则
 * 
 * @author Freedom
 * 
 */
public class FilterChain implements Filter {

	// 保存过滤器对象的链表
	private List<Filter> filters = null;

	public List<Filter> getFilters() {
		return filters;
	}

	public void setFilters(List<Filter> filters) {
		this.filters = filters;
	}

	public FilterChain() {
		filters = new ArrayList<Filter>();
	}

	// 添加过滤器对象
	// 该方法返回对象本身的目的是为了,能够链式的调用方法 ,如:this.addFilter(f).addFilter(f)...
	public Filter addFilter(Filter f) {
		if (!filters.contains(f)) {
			filters.add(f);
		}
		return this;
	}

	// @Override
	// public void doFilter(Request req, Response resp) {
	// for (Filter f : filters) {
	// f.doFilter(req, resp);
	// }
	// }

	// 计算器
	int count = 0;

	@Override
	public void doFilter(Request req, Response resp, FilterChain chain) {

		if (count == filters.size()) {
			return;
		}

		Filter filter = filters.get(count);
		count++;
		filter.doFilter(req, resp, chain);

	}

}

4.1.3、请求消息实体及响应消息实体

package net.oschina.design.chainofresponsibility.finalfilter;

/**
 * 客户端到服务端发送消息的对象
 * 
 * @author Freedom
 * 
 */
public class Request {

	// 简单期间,只定义该属性
	public String reqMsg;

	public String getReqMsg() {
		return reqMsg;
	}

	public void setReqMsg(String reqMsg) {
		this.reqMsg = reqMsg;
	}

}


package net.oschina.design.chainofresponsibility.finalfilter;

/**
 * 响应对象,服务端向客户端发消息的对象
 * 
 * @author Freedom
 * 
 */
public class Response {

	public String respMsg;

	public String getRespMsg() {
		return respMsg;
	}

	public void setRespMsg(String respMsg) {
		this.respMsg = respMsg;
	}

}

4.1.4、主函数

package net.oschina.design.chainofresponsibility.finalfilter;

public class Main {

	public static void main(String[] args) {

		Request req = new Request();
		req.setReqMsg("xxx被潜规则<script>,真的很SB,且行且珍惜");

		FilterChain chain = new FilterChain();
		chain.addFilter(new ScriptFilter());
		chain.addFilter(new SensitiveFilter());

		chain.doFilter(req, new Response(), chain);
	}

}   

运行结果:



 

4.2、程序运行分析

(1)Debug模式:



 

 (2)序列图



 

  • 大小: 16.8 KB
  • 大小: 33.5 KB
  • 大小: 10.1 KB
分享到:
评论

相关推荐

    spring责任链模式详解

    责任链模式是软件设计模式中的一种行为模式,它允许将请求沿着处理者对象的链进行传递,直到某个对象处理该请求。在Spring框架中,责任链模式被广泛应用于AOP(面向切面编程)和事件处理等场景。下面将详细阐述责任...

    设计模式之责任链模式源码

    责任链模式是设计模式中的一种行为模式,它允许在对象之间建立一条处理请求的链条,每个对象都包含对请求的处理逻辑,以及将请求传递给下一个对象的能力。这种模式使得请求可以在链上的对象之间传递,直到被某个对象...

    设计模式之职责链模式(ChainOfResponsibilityPattern)

    职责链模式(ChainOfResponsibilityPattern)是一种行为设计模式,主要目的是通过建立一个处理请求的对象链,使得请求可以在链上的各个对象间传递,直到被某个对象处理。这种模式可以有效地解耦请求发起者和处理者,...

    责任链模式代码

    责任链模式是一种设计模式,它允许我们把请求沿着处理者对象的链进行传递,直到某个对象处理这个请求。这种模式让请求的发送者和接收者解耦,因为发送者无需知道哪个对象会处理请求,而接收者也无需知道请求来自哪里...

    设计模式 - 职责链模式(C++实例)

    职责链模式(Chain of Responsibility)是一种行为设计模式,它的核心思想是将一系列处理请求的对象组织成一条链,每个对象都包含对请求的处理或传递的责任。在C++中实现职责链模式,我们可以创建一个抽象处理器类,...

    责任链模式Demo

    责任链模式是一种设计模式,它允许我们通过定义一系列处理请求的对象来形成一条链,每个对象都包含对请求的处理逻辑,以及将请求传递给链中下一个对象的能力。这种模式使得我们可以将请求的发送者和接收者解耦,使得...

    设计模式-责任链模式

    责任链模式是一种行为设计模式,它允许我们把请求沿着处理者对象的链式结构进行传递,直到某个对象处理这个请求。这种模式使得我们能够将请求的发送者与接收者解耦,同时也允许在运行时动态地改变处理顺序或添加新的...

    JAVA设计模式之行为模式 责任链模式和状态模式

    本篇将探讨两种重要的行为设计模式:责任链模式(Chain of Responsibility Pattern)和状态模式(State Pattern)。 **责任链模式**是一种使多个对象都有机会处理请求的模式,避免请求发送者与接收者之间的耦合。在...

    职责链模式模型代码

    职责链模式(Chain of Responsibility)是一种行为设计模式,它允许我们沿着对象链传递请求,让每个对象决定是否处理这个请求,或者将请求传递给链中的下一个对象。在C#中,我们可以利用类和接口来实现这种模式。让...

    设计模式之责任链模式(Chain)

    责任链模式是一种行为设计模式,它的核心思想是将请求的发送者和接收者解耦,通过将多个处理对象串联成一个处理链,使得请求沿着这个链进行传递,直到被某个对象处理。这种模式使得系统更加灵活,可以在运行时动态...

    责任链模式例子

    责任链模式是一种设计模式,它允许我们通过定义一系列处理请求的对象来解耦发送者和接收者。在责任链模式中,每个对象都是链上的一个节点,可以处理请求的一部分或者将请求传递给链上的下一个对象。这种模式使得系统...

    第17章_职责链模式.ppt

    【职责链模式】是行为型模式的一种,其主要动机是解耦请求的发送者和处理者。在职责链中,多个对象可以接收并处理同一个请求,这些对象形成一条链,请求沿着链传递,直到某个对象负责处理。这种方式减少了对象间的...

    责任链模式小demo

    责任链模式是一种设计模式,它允许我们通过定义一系列处理对象(过滤器)形成一个链,这些对象依次处理请求,而发送者无需知道哪个对象具体处理请求。这种模式将请求的发送者与接收者解耦,增加了系统的灵活性和可...

    【设计模式】之责任链模式1

    责任链模式是一种行为设计模式,它允许将请求沿着处理者对象的链进行发送,而接收者可以在链中的任何位置处理该请求。这种模式的核心思想是将处理请求的对象组织成一个链条,每个对象(节点)都包含对下个处理者的...

    责任链模式学习

    责任链模式是一种行为设计模式,它允许我们定义一系列处理请求的对象,这些对象形成一个链,请求沿着这个链传递,直到某个对象能够处理它。这种方式使得我们可以将请求的发送者和接收者解耦,同时增加了系统扩展的...

    设计模式之责任链模式程序

    一、责任链模式 现有 “战士”、“班长”、“排长”、“连长”,“营长”五种角色,当有人要请假时要进行以下处理 1.只能是下级象上级请假(如“排长”只能向“连长请假”) 2.班长可以批准1天内的假期,排长批5天,...

    设计模式之责任链模式Java实现

    责任链模式(Chain of Responsibility)是一种行为设计模式,它允许将请求沿着处理者对象的链进行传递,直到某个对象能够处理这个请求为止。在Java中,我们可以通过接口和类的组合来实现这种模式。让我们深入探讨...

    设计模式的责任链模式的例子

    责任链模式(Chain of Responsibility Pattern)是设计模式中的一种行为模式,它的主要目的是将请求的发送者和接收者解耦,使得多个对象有机会处理这个请求,形成一条责任链。在这个链上,请求会沿着链传递,直到有...

    责任链模式 C++ 实现

    责任链模式是一种设计模式,它允许我们通过定义一系列处理对象(每个对象称为一个节点),将请求在这些对象之间传递,直到被某个节点处理或者传递完整个链条。这种模式的主要优点在于解耦了发送者和接收者,使得系统...

Global site tag (gtag.js) - Google Analytics