原文:https://www.relaxheart.cn/to/master/blog?uuid=86
什么叫责任链模式?
【专业】:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
【通俗】:举个例子,有时候,出了某件事,我们去解决,找到A,结果A踢皮球,说这不关我的事,去找B解决,然后我们就去找B,结果B也说,这跟我没关系,快去找C,就这样,我们就被踢来踢去,这就是责任链模式的思想,在找到正确的人解决之前,我们被不断的踢给一个有一个人。
责任链模式适用的场景?
1.多个对象可以处理同一个请求,但具体由哪个对象处理则在运行时动态决定。
- 在请求处理者不明确的情况下向对个对象中的一个提交一个请求。
- 需要动态处理一组对象处理请求。
如何使用责任链:代码示例
职责链模式需要一个总接口,用来定义处理对象的公共部分(一般使用抽象类来定义),公共部分包括:一个后继处理器,设置和获取后继处理器的方法,具体的请求处理方法(这个方法需要在每个具体处理对象中实现)。
需求:现在有一个用户信息列表,我们要对具体的每一个用户姓名、身份证、手机号实现脱敏处理。
类图:
类图.png
ConcealFieldUtils.java 三要素信息脱敏工具类
/**
* @author 王琦<QQ.email>1124602935@qq.com<QQ.email>
* @date 19/3/12 下午18:03
* @description 用户三要素信息(姓名、身份证、手机号)脱敏处理工具类
*/
public class ConcealFieldUtils {
/**
* 脱敏姓名
* 脱敏规则:姓氏脱敏
* @param val
* @return
*/
public static String modifyName(String val){
if (StringUtils.isEmpty(val) || val.indexOf("-") != -1){
return val;
}
StringBuilder sb = new StringBuilder(val);
return sb.replace(0,1, "*").toString();
}
/**
* 手机号脱敏
* 脱敏规则:保留前三后四,中间脱敏
* @param val
* @return
*/
public static String modifyMobile(String val){
if (StringUtils.isEmpty(val) || val.indexOf("-") != -1){
return val;
}
return val.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2");
}
/**
* 身份证脱敏
* 脱敏规则:保留前六后四,中间脱敏
* @param val
* @return
*/
public static String modifyIdNumber(String val){
if (StringUtils.isEmpty(val) || val.indexOf("-") != -1){
return val;
}
if (val.length() == 15){
val = val.replaceAll("(\\d{6})\\d{5}(\\d{4})","$1*****$2");
}
if (val.length() == 18){
val = val.replaceAll("(\\d{6})\\d{8}(\\d{4})","$1********$2");
}
return val;
}
}
UserInfo.java用户信息
/**
* @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
* @Date: 2019-5-18 0018 8:02
* @Description: 待处理对象 : 用户信息
*/
public class UserInfo implements Serializable {
private String realName;
private String mobile;
private String idNumber;
public UserInfo(){}
public UserInfo(String realName, String mobile, String idNumber) {
this.realName = realName;
this.mobile = mobile;
this.idNumber = idNumber;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getIdNumber() {
return idNumber;
}
public void setIdNumber(String idNumber) {
this.idNumber = idNumber;
}
/**
* 构造待处理的用户信息列表
* @return
*/
public static List<UserInfo> instanceUserInfoList(){
UserInfo wangdandan = new UserInfo("王蛋蛋", "18400000000", "610364223329283746");
UserInfo xiaoming = new UserInfo("小明", "18722222222", "610364223666663777");
UserInfo tiechui = new UserInfo("张铁锤", "15255557865", "610234223655668976");
// 待处理的用户列表
List<UserInfo> list = new ArrayList<UserInfo>(){{
add(wangdandan);
add(xiaoming);
add(tiechui);
}};
return list;
}
}
UserInfoHandle.java 处理者
/**
* @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
* @Date: 2019-5-18 0018 8:02
* @Description: 用户信息处理器
*/
public interface UserInfoHandle {
void handle(List<UserInfo> list, UserInfoHandleChain chain);
}
UserNameHandle.java 具体处理着:姓名脱敏处理器
/**
* @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
* @Date: 2019-5-18 0018 8:03
* @Description: 用户姓名信息处理器
*/
public class UserNameHandle implements UserInfoHandle {
@Override
public void handle(List<UserInfo> list, UserInfoHandleChain chain) {
System.out.println("姓名脱敏器正在处理...");
for (UserInfo user : list){
String result = ConcealFieldUtils.modifyName(user.getRealName());
user.setRealName(result);
}
System.out.println("姓名脱敏器处理完毕.");
chain.handle(list, chain);
}
}
UserMobileHandle.java 具体处理着:手机号脱敏处理器
/**
* @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
* @Date: 2019-5-18 0018 8:03
* @Description: 用户手机信息处理器
*/
public class UserMobileHandle implements UserInfoHandle {
@Override
public void handle(List<UserInfo> list, UserInfoHandleChain chain) {
System.out.println("手机脱敏器正在处理...");
for (UserInfo user : list){
String result = ConcealFieldUtils.modifyMobile(user.getMobile());
user.setMobile(result);
}
System.out.println("手机脱敏器处理完毕.");
chain.handle(list, chain);
}
}
UserIdNumberHandle.java 具体处理着:身份证脱敏处理器
/**
* @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
* @Date: 2019-5-18 0018 8:03
* @Description: 用户身份证信息处理器
*/
public class UserIdNumberHandle implements UserInfoHandle {
@Override
public void handle(List<UserInfo> list, UserInfoHandleChain chain) {
System.out.println("身份证信脱敏器正在处理...");
for (UserInfo user : list){
String result = ConcealFieldUtils.modifyIdNumber(user.getIdNumber());
user.setIdNumber(result);
}
System.out.println("身份证信脱敏器处理完毕.");
chain.handle(list, chain);
}
}
UserInfoHandleChain.java
/**
* @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
* @Date: 2019-5-18 0018 8:05
* @Description: 责任链模式
*/
public class UserInfoHandleChain implements UserInfoHandle{
// 维护将要参与处理用户信息的handle列表
private List<UserInfoHandle> handles = new ArrayList<>();
//定义一个偏移量
private volatile int index = 0;
public UserInfoHandleChain add(UserInfoHandle handle){
handles.add(handle);
return this;
}
@Override
public void handle(List<UserInfo> list, UserInfoHandleChain chain) {
if (index == handles.size()){
return;
}
UserInfoHandle handle = handles.get(index);
index++;
handle.handle(list, chain);
}
}
FilterChainModelTest.java 测试代码:
/**
* @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
* @Date: 2019-5-18 0018 8:12
* @Description: 责任链模式测试
*
* 要求:对用户信息列表进行处理:姓名、身份证、手机号脱敏
*
*/
public class FilterChainModelTest {
public static void main(String[] args) {
// 待处理的用户信息列表
List<UserInfo> list = UserInfo.instanceUserInfoList();
// <----------- 责任链测试逻辑开始 -------------------->
UserInfoHandleChain chain = new UserInfoHandleChain();
chain.add(new UserNameHandle());
chain.add(new UserMobileHandle());
chain.add(new UserIdNumberHandle());
chain.handle(list , chain);
// <----------- 责任链测试逻辑结束 -------------------->
System.out.println("处理结果:" + JSON.toJSON(list));
}
}
测试结果:
姓名脱敏器正在处理...
姓名脱敏器处理完毕.
手机脱敏器正在处理...
手机脱敏器处理完毕.
身份证信脱敏器正在处理...
身份证信脱敏器处理完毕.
处理结果:[{"realName":"*蛋蛋","mobile":"184****0000","idNumber":"610364********3746"},{"realName":"*明","mobile":"187****2222","idNumber":"610364********3777"},{"realName":"*铁锤","mobile":"152****7865","idNumber":"610234********8976"}]
责任链模式主要优缺点
优点
(1)将请求的发送者和接收者解耦
(2)可以简化你的对象,因为它不需要知道链的结构
(3)通过改变链内的成员或调动他们的次序,允许你动态地新增或者删除责任
缺点
(1)并不保证请求有一定会被执行。如果没有任何对象处理它的话,它可能会落到链尾端之外(这可以是优点,也可以是缺点)
(2)可能不易观察运行时的特征,有碍于排错
网友评论