责任链模式与模版模式

46 阅读2分钟

在 Java 开发中,责任链模式和模板模式是两种常用的设计模式,它们解决不同类型的问题,具有各自独特的应用场景。

1. 责任链模式(Chain of Responsibility Pattern)

定义:创建一个对象链,每个对象都有机会处理请求。请求沿着这条链传递,直到有一个对象处理它为止。

核心角色

  • 抽象处理者(Handler):定义处理请求的接口,包含一个后继处理者的引用

  • 具体处理者(ConcreteHandler):实现处理请求的方法,如果不能处理则传递给下一个处理者

  • 客户端(Client):创建责任链并提交请求 Java 实现示例

// 抽象处理者
public abstract class Handler {
    protected Handler nextHandler;
    
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }
    
    public abstract void handleRequest(Request request);
}

// 具体处理者1
public class ConcreteHandler1 extends Handler {
    @Override
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE1) {
            System.out.println("ConcreteHandler1 处理请求");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

// 具体处理者2
public class ConcreteHandler2 extends Handler {
    @Override
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE2) {
            System.out.println("ConcreteHandler2 处理请求");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        Handler handler1 = new ConcreteHandler1();
        Handler handler2 = new ConcreteHandler2();
        
        handler1.setNextHandler(handler2);
        
        Request request1 = new Request(RequestType.TYPE1);
        Request request2 = new Request(RequestType.TYPE2);
        
        handler1.handleRequest(request1); // 由handler1处理
        handler1.handleRequest(request2); // 由handler2处理
    }
}

应用场景

  • 请求需要被多个对象中的一个或多个处理时(如日志系统、过滤器链)
  • 不确定具体处理者时(如审批流程)
  • Servlet 中的 FilterChain、Spring Security 的过滤器链

2. 模板模式(Template Pattern)

定义:定义一个操作中的算法骨架,将一些步骤延迟到子类中实现。模板方法使得子类可以不改变算法结构即可重定义算法的某些特定步骤。

核心角色

  • 抽象类(AbstractClass):定义算法骨架和抽象方法

  • 具体子类(ConcreteClass):实现抽象方法,完成特定步骤

Java 实现示例

// 抽象类
public abstract class AbstractTemplate {
    // 模板方法,定义算法骨架
    public final void templateMethod() {
        step1();
        step2();
        step3();
        if (hookMethod()) {
            step4();
        }
    }
    
    protected void step1() {
        System.out.println("执行步骤1(默认实现)");
    }
    
    protected abstract void step2(); // 抽象步骤,必须由子类实现
    
    protected void step3() {
        System.out.println("执行步骤3(默认实现)");
    }
    
    protected abstract void step4(); // 抽象步骤,必须由子类实现
    
    // 钩子方法,子类可以选择性覆盖
    protected boolean hookMethod() {
        return true;
    }
}

// 具体子类
public class ConcreteTemplate extends AbstractTemplate {
    @Override
    protected void step2() {
        System.out.println("ConcreteTemplate 执行步骤2");
    }
    
    @Override
    protected void step4() {
        System.out.println("ConcreteTemplate 执行步骤4");
    }
    
    @Override
    protected boolean hookMethod() {
        return true; // 可以根据需要返回不同的值
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        AbstractTemplate template = new ConcreteTemplate();
        template.templateMethod();
    }
}

应用场景

  • 多个子类有公共的方法,且逻辑基本相同时
  • 重要、复杂的算法,核心算法可以设计为模板方法
  • 重构时,把相同代码抽取到父类中
  • Spring 中的 JdbcTemplate、HttpServlet 的 doGet/doPost 方法