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
上一篇下一篇

猜你喜欢

热点阅读