设计模式之责任链模式

责任链模式是一种设计模式,常用于处理一系列连续的审批或过滤任务。在该模式中,每个处理者只负责自己的部分工作,并将未完成的任务传递给下一个处理者,从而避免了大量条件判断和单一职责原则的违背。例如,不同层级的领导审批请假请求,通过责任链模式,可以灵活地添加或移除审批层级,符合开闭原则。具体实现包括抽象过滤器、具体过滤器实现、过滤器上下文和过滤器管理类等组件。
摘要由CSDN通过智能技术生成

责任链模式

  • 概念
  • 类图
  • 代码实例

概念

例如不同层级的领导,审批权限不一样,不同的请假请求会流向不同的管理层,如果使用传统的方式 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}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值