行为型模式(Behavioral Pattern)是对不同的对象之间划分责任和算法的抽象化;
行为型模式共有11种:
■ 模板方法模式
■ 命令模式
■ 责任链模式
■ 策略模式
■ 迭代器模式
■ 中介者模式
■ 观察者模式
■ 备忘录模式
■ 访问者模式
■ 状态模式
■ 解释器模式
一、责任链模式的简介
■ 使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系;
将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止;
责任链模式的重点是在“链”上,由一条链去处理相似的请求,在链中决定谁来处理这个请求,并返回相应的结果;

image.png
责任链模式2个角色:
■ 抽象处理者(Handler)角色:
该角色对请求进行抽象;
■ 具体处理者(Concrete Handler)角色:
该角色接到请求后,可以选择将请求处理掉,或者将请求传给下一个处理者;
/**
* 抽象处理者
*/
public abstract class Handler {
private Handler successor;
// 处理方法
public abstract void handleRequest();
public Handler getSuccessor(){
return successor;
}
public void setSuccessor(Handler successor) {
this.successor = successor;
}
}
/**
* 具体处理者
*/
public class ConcreteHandler extends Handler{
// 处理请求
@Override
public void handleRequest() {
if(getSuccessor() != null){
System.out.println("请求传递给" + getSuccessor());
getSuccessor().handleRequest();
}else{
System.out.println("请求处理");
}
}
}
/**
* 应用代码
*/
public class ClientDemo {
public static void main(String[] args){
Handler h1 = new ConcreteHandler();
Handler h2 = new ConcreteHandler();
h1.setSuccessor(h2);
h1.handleRequest();
}
}
# 控制台输出:
请求传递给com.example.favoritecode.handler.ConcreteHandler@6267c3bb
请求处理
二、责任链模式的优缺点
■ 责任链模式的优点:
责任链模式将请求和处理分开,请求者不知道是谁处理的,处理者可以不用知道请求的全貌;
提高系统的灵活性
■ 责任链模式的缺点:
降低程序的性能,每个请求都是从链头遍历到链尾,当链比较长的时候,性能会大幅下降;
不易于调试,由于采用了类似递归的方式,调试的时候逻辑比较复杂;
三、责任链模式的应用场景
Struts2的核心控件FilterDispatcher是一个Servlet过滤器,该控件就是采用责任链模式,可以对用户请求进行层层过滤处理;
■ 一个请求需要一系列的处理工作;
■ 业务流的处理,
例如,文件审批;
■ 对系统进行补充扩展;
四、责任链模式的实例
击鼓传花便是责任链模式的应用;

image.png
/**
* 传花者抽象类
*/
public abstract class Player {
private Player successor;
public void setSuccessor(Player successor) {
this.successor = successor;
}
public abstract void handler(int i);
/**
* 传递给下一个
* @param index
*/
public void next(int index){
if(successor != null){
successor.handler(index);
}else{
System.out.println("游戏结束");
}
}
}
/**
* 具体传花者 PlayerA
*/
public class PlayerA extends Player{
public PlayerA(Player successor){
this.setSuccessor(successor);
}
@Override
public void handler(int i) {
if(i == 1){
System.out.println("PlayerA 喝酒");
}else{
System.out.println("PlayerA 把花像下传");
next(i);
}
}
}
/**
* 具体传花者 PlayerB
*/
public class PlayerB extends Player{
public PlayerB(Player successor){
this.setSuccessor(successor);
}
@Override
public void handler(int i) {
if(i == 2){
System.out.println("PlayerB 喝酒");
}else{
System.out.println("PlayerB 把花像下传");
next(i);
}
}
}
/**
* 具体传花者 PlayerC
*/
public class PlayerC extends Player{
public PlayerC(Player successor){
this.setSuccessor(successor);
}
@Override
public void handler(int i) {
if(i == 3){
System.out.println("PlayerC 喝酒");
}else{
System.out.println("PlayerC 把花像下传");
next(i);
}
}
}
/**
* 具体传花者 PlayerD
*/
public class PlayerD extends Player{
public PlayerD(Player successor){
this.setSuccessor(successor);
}
@Override
public void handler(int i) {
if(i == 4){
System.out.println("PlayerD 喝酒");
}else{
System.out.println("PlayerD 把花像下传");
next(i);
}
}
}
import java.security.SecureRandom;
/**
* 击鼓者
*/
public class DrumBeater {
public static void main(String[] args){
// // 创建一个链
Player player = new PlayerA(new PlayerB(new PlayerC(new PlayerD(null))));
SecureRandom random = new SecureRandom();
/**
* 因为只模拟了4个人,所以 1 ~ 4随机
* 如果 > 4 ,就跳出这4个人的范围,游戏就结束了 ,没人喝酒了
*/
int index = random.nextInt(4) + 1;
System.out.println("随机数 : " + index);
player.handler(index);
}
}
# 控制台输出:
随机数 : 3
PlayerA 把花像下传
PlayerB 把花像下传
PlayerC 喝酒
参考:
摘录 《设计模式(Java版)》韩敬海主编;(微信读书APP中有资源,可以直接阅读)
网友评论