当前位置: > > > Java - GoF设计模式详解15(责任链模式)

Java - GoF设计模式详解15(责任链模式)

十五、责任链模式

1,基本介绍

(1)责任链模式(Chain of Responsibility):把可以响应请求的对象链接起来,并在链中传递请求,直到有一个对象处理这个请求。从而保证多个对象都有机会处理请求,减少请求的发送者与接收者之间的耦合。

(2)该模式中包含的角色及其职责如下:
  • 抽象处理者(Handler)角色:定义了处理请求的接口,并且可以设置后继处理者。
  • 具体处理者(Concrete Handler)角色:实现了处理请求的方法,并且可以设置后继处理者。如果无法处理请求,则将请求转发给后继处理者。

2,使用样例

(1)下面我通过用户订单请求的处理(订货量小于 1000 的由经理处理,小于 10000 的由主任处理,大于等于 10000 的由董事长处理)来演示责任链模式的使用。首先我们定义一个订单请求类 OrderRequest
// 订单请求类
public class OrderRequest {
  private String customer;  //客户姓名
  private int amount;  //订货量

  public OrderRequest(String customer, int amount) {
    this.customer = customer;
    this.amount = amount;
  }

  public String getCustomer() {
    return customer;
  }

  public int getAmount() {
    return amount;
  }
}

(2)接着定义一个抽象的处理者类 OrderHandler
// 抽象处理者类
public abstract class OrderHandler {
  // 下一个处理者
  protected OrderHandler successor;

  // 设置下一个处理者
  public void setSuccessor(OrderHandler successor) {
    this.successor = successor;
  }

  // 处理订单请求的方法
  public abstract void handleOrder(OrderRequest request);
}

(3)然后就是定义3个具体的处理者类,分别是 ManagerOrderHandlerDirectorOrderHandlerCEOOrderHandler
// 经理级别订单处理
public class ManagerOrderHandler extends OrderHandler {
  @Override
  public void handleOrder(OrderRequest request) {
    if (request.getAmount() < 1000) {
      System.out.println("经理处理来自" + request.getCustomer() + "的订单,订货量为" 
              + request.getAmount());
    } else {
      successor.handleOrder(request);
    }
  }
}

// 主任级别订单处理
public class DirectorOrderHandler extends OrderHandler {
  @Override
  public void handleOrder(OrderRequest request) {
    if (request.getAmount() < 10000) {
      System.out.println("主任处理来自" + request.getCustomer() + "的订单,订货量为" 
              + request.getAmount());
    } else {
      successor.handleOrder(request);
    }
  }
}

// 董事长级别订单处理
public class CEOOrderHandler extends OrderHandler {
  @Override
  public void handleOrder(OrderRequest request) {
    System.out.println("董事长处理来自" + request.getCustomer() + "的订单,订货量为"
            + request.getAmount());
  }
}

(4)最后我们使用责任链模式来处理用户的订单请求,我们先设置了三个处理者对象 managerdirectorceo,并且设置了它们的后继处理者。然后,我们发送了 4 个订单请求,每个请求都会在责任链上流动,直到有一个处理者能够处理该请求为止。
public class Test {
  public static void main(String[] args) {
    // 创建处理者对象
    OrderHandler manager = new ManagerOrderHandler();
    OrderHandler director = new DirectorOrderHandler();
    OrderHandler ceo = new CEOOrderHandler();
    // 设置后继处理者
    manager.setSuccessor(director);
    director.setSuccessor(ceo);
    // 发送请求
    manager.handleOrder(new OrderRequest("乔布斯", 12000));
    manager.handleOrder(new OrderRequest("李老板", 500));
    manager.handleOrder(new OrderRequest("hangge", 1500));
    manager.handleOrder(new OrderRequest("刘总", 50000));
  }
}

附一:JDK 中的责任链模式

(1)java.util.logging 包中的日志系统使用了责任链模式。当 Logger 对象收到一条日志消息时,它会将消息发送到它的后继节点。Logger 对象的后继节点可以是其他 Logger 对象,也可以是控制台、文件或其他输出目的地。这样,Logger 对象就可以将日志消息发送到多个输出目的地,从而实现了责任链模式的效果。
public class Test {
  private static final Logger logger = Logger.getLogger(Test.class.getName());

  public static void main(String[] args) {
    logger.info("This is an info message.");
    logger.warning("This is a warning message.");
    logger.severe("This is a severe message.");
  }
}

(2)在上面的示例代码中,我们并没有显式地创建 Logger 对象的后继节点。这是因为,在默认情况下,Logger 对象的后继节点是由 Java 虚拟机的日志记录配置文件决定的。如果要修改 Logger 对象的后继节点,可以使用 Logger 对象的 addHandler() 方法来添加新的后继节点。例如,可以使用以下代码来将一个文件输出流添加为 Logger 对象的后继节点:
  • 下面的代码中,我们使用了 FileHandler 类来创建一个文件输出流,然后使用 Logger 对象的 addHandler() 方法将该输出流添加为 Logger 对象的后继节点。这样,Logger 对象就可以将日志消息发送到两个输出目的地:控制台和文件。
public class Test {
  private static final Logger logger = Logger.getLogger(Test.class.getName());

  public static void main(String[] args) throws Exception {
    FileHandler fileHandler = new FileHandler("example.log");
    logger.addHandler(fileHandler);

    logger.info("This is an info message.");
    logger.warning("This is a warning message.");
    logger.severe("This is a severe message.");
  }
}

附二:Spring 中的责任链模式

1,Spring MVC 中的拦截器(Interceptor)

    拦截器是 Spring MVC 的一种常用机制,用于拦截请求并执行特定的操作。拦截器通常是按照定义的顺序依次执行,形成一个责任链。

2,Spring AOP 中的切面(Aspect)

    Spring AOP 支持在特定方法调用前或之后执行某些操作,这些操作被称为切面。多个切面可以通过配置的优先级或执行顺序来构建责任链。

3,Spring 的事件传递机制(ApplicationEvent)

    Spring 支持在应用中传递事件,这些事件可以被多个监听器(Listener)接收并处理。这些监听器可以按照定义的优先级或执行顺序依次执行,形成一个责任链。

附三:JavaScript 中的责任链模式

    在 JavaScript 中,可以使用事件冒泡(event bubbling)机制来实现事件的传递。在事件冒泡中,事件从目标元素开始向上传递,每经过一个父元素就被触发一次。这种机制可以让多个元素对同一个事件进行响应,形成一个责任链。
评论0