责任链模式(Chain of Responsibility)是用一系列类(classes)试图处理一个请求 request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递 request. 也就是说,来了一个请求,A 类先处理,如果没有处理,就传递到 B 类处理,如果没有处理,就传递到 C 类处理,就这样象一个链条(chain)一样传递下去。在这种模式下,通常每个接受者都包含对另一个接受者的引用。像Struts2的拦截器、servlet的Filter等都是使用责任链模式。
下面就举例说明这一设计模式。当在产品开发过程中,测试者、开发者、产品经理和需求人员会根据bug的数目产生一个责任链(假设是根据bug的数目^_^)。
首先对产品bug的负责人抽象出一个责任容器和一个责任链:
public abstract class ProductHandle {
protected ProductHandle productHandle;
public ProductHandle getProductHandle() {
return productHandle;
}
public void setProductHandle(ProductHandle productHandle) {
this.productHandle = productHandle;
}
//根据bug数目来请求责任人来处理
public abstract void handleBug(int bugs);
//设置责任链
public static ProductHandle createHandle(){
ProductHandle developer = new Developer();
ProductHandle producter = new ProductManager();
ProductHandle customer = new CustomerDemand();
developer.setProductHandle(producter);
producter.setProductHandle(customer);
return developer;
}
}
有bug了,提交给程序员,程序员要继承这个责任:
public class Developer extends ProductHandle {
@Override
public void handleBug(int bugs) {
if(bugs <= 100){
System.out.println("浏览器清除一下缓存,还不行的话我就处理这些Bug: " + bugs);
}else{
productHandle.handleBug(bugs);
}
}
}
bug太多,业务都走不下去了,把责任推给产品(肯定产品设计有问题的啦):
public class ProductManager extends ProductHandle {
@Override
public void handleBug(int bugs) {
if(bugs <= 1000){
System.out.println("开发的没问题吗,业务走不通?好吧,我来解决这些bug: " + bugs);
}else{
productHandle.handleBug(bugs);
}
}
}
根据需求产品经理对这些bug也无能为力,还是跟需求谈一下吧:
public class CustomerDemand extends ProductHandle {
@Override
public void handleBug(int bugs) {
if(bugs<=10000){
System.out.println("这么多bug,产品设计的有问题吧(怼不过产品)!好吧,我改一下需求,解决这些bug: " + bugs);
}else{
System.out.println("bug太多,产品取消,大家自行解散!bug: " + bugs);
}
}
}
这样就形成了一个责任链,还要一个测试人员,要是测试出了bug就列给责任人:
public class Tester {
private ProductHandle productHandle;
public void setProductHandle(ProductHandle productHandle) {
this.productHandle = productHandle;
}
public void handleBugs(int bugs){
productHandle.handleBug(bugs);
}
}
上午饮茶看新闻,下午喝咖啡敲一个多小时的代码,经过了三个月紧锣密鼓的开发,产品终于成型了,尽情的测试吧:
public class BugsTest {
public static void main(String[] args) {
Tester tester = new Tester();
tester.setProductHandle(ProductHandle.createHandle());
int[] bugs = {66,777,8888,99999};
for (int bug : bugs) {
tester.handleBugs(bug);
}
}
}
运行结果如下:
第一次测试:浏览器清除一下缓存,还不行的话我就处理这些Bug: 66
第二次测试:开发的没问题吗,业务走不通?好吧,我来解决这些bug: 777
第三次测试:这么多bug,产品设计的有问题吧(怼不过产品)!好吧,我改一下需求,解决这些bug: 8888
第四次测试:bug太多,产品取消,大家自行解散!bug: 99999
责任链模式的优缺点:
优点:
1、降低耦合度,将请求的发送者和接受者解耦;
2、简化了对象,使得对象不需要知道链的结构;
3、增强给对象指派职责的灵活性,允许动态的新增或者删除责任;
4、增加新的请求处理类很方便
缺点:
1、效率低,系统性能将受到影响,并且代码调试起来不方便,可能造成循环调用;
2、扩展性差,因为一定要有一个统一的接口或者抽象类。