用过apache mina的朋友都知道mina core包中有一个非常重要的包,即IoFilterChain,IoFilterChain的过滤模型如下图所示:
而IoFilterChain的java基础即博主今天要和大家聊的java设计模式之责任链模式:
首先给大家看下百度百科对责任链模式的定义:
责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
我们现在以一个具体实例和大家说明下责任链的流程,通常我们吃一个苹果会经历如下步骤:
第一步,洗苹果;第二步,给苹果削皮;第三步,切片。
如果用代码来表示以上过程,我相信大家是不是会不假思索的直接执行三个方法,即洗苹果接着削皮接着切片,可是大家有没有想过如果我们多出一个步骤怎么办,比如切片之前去核?那大家是不是会直接再修改之前的代码在加一步去核。其实这样并无不可,只是如果这样下去,我们的代码耦合度极高,且不利于后期的功能扩展。现在我们就借助责任链模式对以上实例进行改造。下面直接贴代码给各位:
1、首先是创建一个苹果对象
/**
* 被处理的对象
* @author suntongxin
*
*/
public class Apple {
//苹果当前的状态
private String state="我是一个苹果";
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
苹果对象只有一个属性,即苹果的当前状态。
2、抽象化一个责任者接口出来
/**
* 抽象的处理接口
* @author suntongxin
*
*/
public interface IHandler {
/**
* 设置下一个处理类
* @param nextHandler
*/
void setNextHandler(IHandler nextHandler);
/**
* 具体处理需求
* @param obj
*/
void handleRequest(Object obj);
}
责任者具备两个方法,一个是具体处理需求的方法(即实际处理对象),一个是设置下一个责任者的方法。
3、实现三个具体的责任者,即洗苹果的责任者、削苹果皮的责任者和给苹果切片的责任者
/**
* 第一个处理者
* @author suntongxin
*
*/
public class HandlerA implements IHandler{
private IHandler nextHandler;
@Override
public void setNextHandler(IHandler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handleRequest(Object obj) {
Apple apple = (Apple)obj;
apple.setState(apple.getState()+"\r\n我被水清洗干净了!");
if(nextHandler!=null){
nextHandler.handleRequest(obj);
}
}
}
/**
* 第二个处理者
* @author suntongxin
*
*/
public class HandlerB implements IHandler{
private IHandler nextHandler;
@Override
public void setNextHandler(IHandler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handleRequest(Object obj) {
Apple apple = (Apple)obj;
apple.setState(apple.getState()+"\r\n我被削皮了!");
if(nextHandler!=null){
nextHandler.handleRequest(obj);
}
}
}
/**
* 第三个处理者
* @author suntongxin
*
*/
public class HandlerC implements IHandler{
private IHandler nextHandler;
@Override
public void setNextHandler(IHandler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handleRequest(Object obj) {
Apple apple = (Apple)obj;
apple.setState(apple.getState()+"\r\n我被切片了!");
if(nextHandler!=null){
nextHandler.handleRequest(obj);
}
}
}
4、实际调用过程
/**
* 实际调用过程
* @author suntongxin
*
*/
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
//实例化被处理对象和三个处理者
Apple apple = new Apple();
HandlerA handlerA = new HandlerA();
HandlerB handlerB = new HandlerB();
HandlerC handlerC = new HandlerC();
//设置处理者的下一个处理者,并先第一个处理者发起任务
handlerA.setNextHandler(handlerB);
handlerB.setNextHandler(handlerC);
handlerA.handleRequest(apple);
//打印最终被处理对象的状态
System.out.println(apple.getState());
}
}
我们可以看到执行该方法之后获得如下打印结果:
我是一个苹果
我被水清洗干净了!
我被削皮了!
我被切片了!
我们可以发现经过以上改造的代码整洁清晰、并无大量的if/else语句,而且如果我们需要扩展多个步骤只需实现IHandler接口类即可。
而apache mina中本着接口功能单一化的原则,责任者接口有两个,一个IoFilter一个内部接口NextFilter,而作为其默认实现IoFilterAdapter则实现了责任者之间的传递。