java实现filter的责任链设计模式
2019-06-15 本文已影响0人
iamdev
今天心血来潮,突然想起tomcat,jetty等servlet容器,有一个设计模式,很有意思的,那就是filter,
简单回顾一下filter,当我们把filter注册在web.xml里面的话,同时按照一定的顺序,假设我们有三个filter
那么就会先调用A->B->C,然后再从C回到A
伪代码:
public void doFilter(Request req,Response resp,Chain chain){
doSomething();
chain.doChain(req,resp);
doSomething();
}
那么我们来实现一下,现在抽象成一个现实场景:
假设有一群小朋友,小明,小张,小红,小兰,他们在吃一袋苹果,按照顺序吃苹果
小明吃完之后,把那一袋苹果交给小张,小张吃完再交给小红。。。
然后小兰再交回给小红,小红再交给小张,最后重新到小明手中。
每次经过一个人手中的时候,统计一下苹果的剩余数量,每次交接,每个人都吃掉一个苹果。
描述完要求之后,接下来就是编码实现这个场景:
我们抽象一个People接口,这个接口负责处理苹果袋,和把苹果交给下一个人
public interface People {
void handle(AppleBag appleBag,Transfer transfer);
}
我们还需要一个苹果袋对象,这个对象的构造方法,传递苹果数量。同时支持getApple()拿掉苹果的数量和获取苹果数量getAppleNumber()
public class AppleBag {
private int appleNumber;
public AppleBag(int appleNumber) {
this.appleNumber = appleNumber;
}
public void getApple(int appleNumber) {
this.appleNumber = this.appleNumber - appleNumber;
}
public int getAppleNumber() {
return appleNumber;
}
}
抽象一个Transfer接口,负责怎么传递苹果,简单理解就是苹果传递器,绝对怎么传递苹果,可以把理解为指挥所有小朋友的一个老师。
public interface Transfer {
void transfer(AppleBag appleBag);
}
接下来实现一个People对象,该对象的构造参数可以传递people的名字,
handle方法中处理苹果和打印苹果数量,以及按照老师(Transfer)的指令交接苹果袋给下一个人。
public class PeopleImpl implements People {
private String name;
public PeopleImpl(String name) {
this.name = name;
}
@Override
public void handle(AppleBag appleBag, Transfer transfer) {
System.out.println(String.format("%s在吃苹果,苹果到手的时候数量为%s", name, appleBag.getAppleNumber()));
System.out.println(String.format("%s把苹果包交到下一个人", name));
appleBag.getApple(1); //从苹果袋取出一个苹果
transfer.transfer(appleBag); //按照老师的意思传递苹果袋给下一个人
System.out.println(String.format("苹果包重新拿回%s的手上,剩余%s", name, appleBag.getAppleNumber()));
appleBag.getApple(1); //从苹果袋取出一个苹果
}
}
接下来实现一个Transfer对象,决定怎么分发苹果。构造参数传入一个排好队的小朋友列表
public class TransferImpl implements Transfer {
private Iterator<People> iter;
public TransferImpl(List<People> peopleList) {
this.iter = peopleList.iterator();
}
private People next() { //获取下一个小朋友
if (iter.hasNext()) {
return iter.next();
}
return null;
}
@Override
public void transfer(AppleBag appleBag) { //获取到小朋友的时候,使用小朋友的处理苹果逻辑,同时传递自己进去
People people = next();
if (people != null) {
people.handle(appleBag, this);
}
}
}
新建一个Main类,测试一下:
public class Main {
public static void main(String[] args) {
List<People> peopleList =new ArrayList<>();
peopleList.add(new PeopleImpl("小明"));//排队
peopleList.add(new PeopleImpl("小红"));
peopleList.add(new PeopleImpl("小张"));
peopleList.add(new PeopleImpl("小兰"));
TransferImpl transfer =new TransferImpl(peopleList);
AppleBag appleBag =new AppleBag(20); //初始化一个20个苹果的苹果袋
transfer.transfer(appleBag);//开始传递苹果
}
}
打印如下:
小明在吃苹果,苹果到手的时候数量为20
小明把苹果包交到下一个人
小红在吃苹果,苹果到手的时候数量为19
小红把苹果包交到下一个人
小张在吃苹果,苹果到手的时候数量为18
小张把苹果包交到下一个人
小兰在吃苹果,苹果到手的时候数量为17
小兰把苹果包交到下一个人
苹果包重新拿回小兰的手上,剩余16
苹果包重新拿回小张的手上,剩余15
苹果包重新拿回小红的手上,剩余14
苹果包重新拿回小明的手上,剩余13