定义:
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,抽象非核心的部分,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。
参考博客:责任链模式
场景:
小明去上学,先洗头,再洗脸,再吃饭,最后出门到学校学习。
常规做法:
1. 比如定义一个动作集合,存储小明的动作。
public class PreparationList {
/**
* 是否洗脸
*/
private boolean washFace;
/**
* 是否洗头
*/
private boolean washHair;
/**
* 是否吃早餐
*/
private boolean haveBreakfast;
public boolean isWashFace() {
return washFace;
}
public void setWashFace(boolean washFace) {
this.washFace = washFace;
}
public boolean isWashHair() {
return washHair;
}
public void setWashHair(boolean washHair) {
this.washHair = washHair;
}
public boolean isHaveBreakfast() {
return haveBreakfast;
}
public void setHaveBreakfast(boolean haveBreakfast) {
this.haveBreakfast = haveBreakfast;
}
}
2. 定义学习类,学习的方法需要再这些前置动作都完成之后才能进行学习。
public class Study {
public void study(PreparationList preparationList) {
if (preparationList.isWashHair()) {
System.out.println("洗脸");
}
if (preparationList.isWashHair()) {
System.out.println("洗头");
}
if (preparationList.isHaveBreakfast()) {
System.out.println("吃早餐");
}
System.out.println("我可以去上学了!");
}
}
带来的问题:
1. study方法需要随着PreparationList内内容的增加或者减少而变动。这就是过度耦合了,本来学习归学习,至于学习之前要做什么,不归学习管。
责任链做法:
public abstract class AbstractPrepareFilter {
private AbstractPrepareFilter nextPrepareFilter;
public AbstractPrepareFilter(AbstractPrepareFilter nextPrepareFilter) {
this.nextPrepareFilter = nextPrepareFilter;
}
public void doFilter(PreparationList preparationList, Study study) {
prepare(preparationList);
if (nextPrepareFilter == null) {
//特有操作
study.study();
} else {
nextPrepareFilter.doFilter(preparationList, study);
}
}
//前置操作
public abstract void prepare(PreparationList preparationList);
}
public class WashHairFilter extends AbstractPrepareFilter {
public WashHairFilter(AbstractPrepareFilter nextPrepareFilter) {
super(nextPrepareFilter);
}
@Override
public void prepare(PreparationList preparationList) {
if (preparationList.isWashHair()) {
System.out.println("洗头");
}
}
}
public class WashFaceFilter extends AbstractPrepareFilter {
public WashFaceFilter(AbstractPrepareFilter nextPrepareFilter) {
super(nextPrepareFilter);
}
@Override
public void prepare(PreparationList preparationList) {
if (preparationList.isWashFace()) {
System.out.println("洗脸");
}
}
}
public class HaveBreakfastFilter extends AbstractPrepareFilter {
public HaveBreakfastFilter(AbstractPrepareFilter nextPrepareFilter) {
super(nextPrepareFilter);
}
@Override
public void prepare(PreparationList preparationList) {
if (preparationList.isHaveBreakfast()) {
System.out.println("吃早餐");
}
}
}
public class Test {
public static void main(String[] args) {
PreparationList preparationList = new PreparationList();
preparationList.setWashFace(true);
preparationList.setWashHair(false);
preparationList.setHaveBreakfast(true);
Study study = new Study();
AbstractPrepareFilter haveBreakfastFilter = new HaveBreakfastFilter(null);
AbstractPrepareFilter washFaceFilter = new WashFaceFilter(haveBreakfastFilter);
AbstractPrepareFilter washHairFilter = new WashHairFilter(washFaceFilter);
washHairFilter.doFilter(preparationList, study);
}
}
分析问题:
1. 不需要修改study方法了。
2.调用方不够简洁,增加或者减少Filter需要改代码,包括顺序改变都没法保证。
责任链做法重构版本:
public interface StudyPrepareFilter {
public void doFilter(PreparationList preparationList, FilterChain filterChain);
}
public class WashHairFilter implements StudyPrepareFilter {
@Override
public void doFilter(PreparationList preparationList, FilterChain filterChain) {
if (preparationList.isWashHair()) {
System.out.println("洗完头发");
}
filterChain.doFilter(preparationList, filterChain);
}
}
public class WashFaceFilter implements StudyPrepareFilter {
@Override
public void doFilter(PreparationList preparationList, FilterChain filterChain) {
if (preparationList.isWashFace()) {
System.out.println("洗完脸");
}
filterChain.doFilter(preparationList, filterChain);
}
}
public class HaveBreakfastFilter implements StudyPrepareFilter {
@Override
public void doFilter(PreparationList preparationList, FilterChain filterChain) {
if (preparationList.isHaveBreakfast()) {
System.out.println("吃完早饭");
}
filterChain.doFilter(preparationList, filterChain);
}
}
public class FilterChain implements StudyPrepareFilter {
private int pos = 0;
private Study study;
private List<StudyPrepareFilter> studyPrepareFilterList;
public FilterChain(Study study) {
this.study = study;
}
public void addFilter(StudyPrepareFilter studyPrepareFilter) {
if (studyPrepareFilterList == null) {
studyPrepareFilterList = new ArrayList<StudyPrepareFilter>();
}
studyPrepareFilterList.add(studyPrepareFilter);
}
@Override
public void doFilter(PreparationList thingList, FilterChain filterChain) {
// 所有过滤器执行完毕
if (pos == studyPrepareFilterList.size()) {
study.study();
}
studyPrepareFilterList.get(pos++).doFilter(thingList, filterChain);
}
}
public class Test {
public static void main(String[] args) {
PreparationList preparationList = new PreparationList();
preparationList.setWashFace(true);
preparationList.setWashHair(false);
preparationList.setHaveBreakfast(true);
Study study = new Study();
StudyPrepareFilter washFaceFilter = new WashFaceFilter();
StudyPrepareFilter washHairFilter = new WashHairFilter();
StudyPrepareFilter haveBreakfastFilter = new HaveBreakfastFilter();
FilterChain filterChain = new FilterChain(study);
filterChain.addFilter(washFaceFilter);
filterChain.addFilter(washHairFilter);
filterChain.addFilter(haveBreakfastFilter);
filterChain.doFilter(preparationList, filterChain);
}
}
好处:
1. 代码的修改和编写不用再更新代码了,可以使用spring的配置文件来配置需要的Filter。
<bean id="filterChain" class="xxx.xxx.xxx.FilterChain">
<property name="studyPrepareFilterList">
<list>
<ref bean="washFaceFilter" />
<ref bean="washHairFilter" />
<ref bean="haveBreakfastFilter" />
</list>
</property>
</bean>