责任链模式
- 概念
- 类图
- 代码实例
概念
例如不同层级的领导,审批权限不一样,不同的请假请求会流向不同的管理层,如果使用传统的方式 if else实现,这样在类中写很多逻辑,不易维护,违反了单一职责,当增加新的层级管理层进而导致修改类,不符合开闭原则。
将各个分支条件转好成各个类,并抽出一个抽象管理类,如果类A没有权限处理该请求那么就会交给下个管理类进行处理,此时类A仅仅包含下个处理类。 通过这种方式将整个一个一个处理类串联起来就是责任链
场景:
当某个操作需要经过多个步骤才能完成时,并且会经过不同处理者,这个时候可以采用责任链模式,当前处理者只需要关系自己的逻辑,处理完后交个下个处理者。
类图
PersonFilter:抽象过滤器
PersonAgeFilter:对年龄过滤
PersonNameFilter:对名字过滤
FilterContext:过滤器上下文(人的有关参数和过滤规则)
FilterManager:过滤器管理类
Person:人的类
Rule:过滤规则
TestFilter:测试类
代码实例
PersonFilter:过滤器类
/**
* @author duanyimiao
* @create 2018-05-23 5:53 PM
* @description
**/
public interface PersonFilter {
//不过滤
int PRIORITY_IGNORE = -1;
int PRIORITY_NAME = 0;
int PRIORITY_AGE = 1;
/**
* @param filterContext 传递在各个过滤器的上下文(参数)
*/
public void setFilter(FilterContext filterContext);
/**
* 设置过滤器的优先级 越小优先级越高
*
* @return
*/
public int getPriority();
}
PersonAgeFilter
/**
* @author duanyimiao
* @create 2018-05-23 6:15 PM
* @description
**/
public class PersonAgeFilter implements PersonFilter {
@Override
public void setFilter(FilterContext filterContext) {
if (filterContext.getPerson().getAge() > filterContext.getRule().getMaxAge()) {
throw new IllegalArgumentException("age is illegal");
}
}
@Override
public int getPriority() {
return PersonFilter.PRIORITY_AGE;
}
}
PersonNameFilter
/**
* @author duanyimiao
* @create 2018-05-23 6:15 PM
* @description
**/
public class PersonNameFilter implements PersonFilter {
@Override
public void setFilter(FilterContext filterContext) {
Person person = filterContext.getPerson();
String name = person.getName();
person.setName(name.replace(filterContext.getRule().getSensitiveWord(),"*"));
}
@Override
public int getPriority() {
return PersonFilter.PRIORITY_NAME;
}
}
FilterContext 过滤上下文
/**
* @author duanyimiao
* @create 2018-05-23 5:52 PM
* @description
**/
public class FilterContext {
private Person person;
private Rule rule;
private List<PersonFilter> filters;
private int curFilterIndex;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public Rule getRule() {
return rule;
}
public void setRule(Rule rule) {
this.rule = rule;
}
public void doFilter(FilterContext context) {
filters.get(curFilterIndex++).setFilter(context);
}
@Override
public String toString() {
return "FilterContext{" +
"person=" + person +
", rule=" + rule +
'}';
}
}
FilterManager 过滤器管理类
/**
* @author duanyimiao
* @create 2018-05-23 5:52 PM
* @description
**/
public class FilterManager {
//真实应用时 使用spring 注入对象
private List<PersonFilter> filters;
private FilterContext filterContext;
public void setFilterContext(FilterContext filterContext) {
this.filterContext = filterContext;
}
public void setFilters(List<PersonFilter> filters) {
this.filters = filters;
}
public void sortFilters() {
//根据优先级进行对 filters排序 priority越小排在前面
Collections.sort(filters, new Comparator<PersonFilter>() {
@Override
public int compare(PersonFilter o1, PersonFilter o2) {
int i = o1.getPriority() - o2.getPriority();
return i;
}
});
}
public void startFilter() {
sortFilters();
for (PersonFilter personFilter : filters) {
if(personFilter.getPriority() == PersonFilter.PRIORITY_IGNORE){
continue;
}
personFilter.setFilter(filterContext);
}
}
}
Person
/**
* @author duanyimiao
* @create 2018-05-23 5:45 PM
* @description
**/
public class Person {
private String name;
private Integer age;
Person(){
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Rule
/**
* @author duanyimiao
* @create 2018-05-23 5:46 PM
* @description
**/
public class Rule {
public String getSensitiveWord(){
return "fuck";
}
public int getMaxAge(){
return 10;
}
}
TestFilter
/**
* @author duanyimiao
* @create 2018-05-23 6:11 PM
* @description
**/
public class TestFilter {
public static void main(String[] args) {
Person person = new Person("fuck me ", 20);
Rule rule = new Rule();
FilterContext filterContext = new FilterContext();
filterContext.setPerson(person);
filterContext.setRule(rule);
try {
List<PersonFilter> filters = Lists.newArrayList();
filters.add(new PersonAgeFilter());
filters.add(new PersonNameFilter());
FilterManager filterManager = new FilterManager();
filterManager.setFilterContext(filterContext);
filterManager.setFilters(filters);
filterManager.startFilter();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("before" + filterContext.getPerson() + " after" + filterContext.getPerson());
}
}
输出结果:
java.lang.IllegalArgumentException: age is illegal
at com.dynamo.filter.fitler.impl.PersonAgeFilter.setFilter(PersonAgeFilter.java:15)
at com.dynamo.filter.fitler.FilterManager.startFilter(FilterManager.java:43)
at com.dynamo.filter.TestFilter.main(TestFilter.java:36)
beforePerson{name='* me ', age=20} afterPerson{name='* me ', age=20}