行为设计模式之责任链

开一个新系列,通过实例的方式解析下各种设计模式,加深理解和应用能力。
理论内容主要来自于《深入设计模式》一书。

本文通过责任链模式实现一个简化的工单处理系统。

设计

uml diagram

实现

TicketHandler - 顶层接口

public interface TicketHandler {  
    String handleTicket(UserTicket ticket);  
}

BaseTicketHandler - 基础抽象类

public abstract class BaseTicketHandler implements TicketHandler{  
    private BaseTicketHandler nextHandler;  
  
    public void setNextHandler(BaseTicketHandler nextHandler) {  
        this.nextHandler = nextHandler;  
    }  
  
    @Override  
    public String handleTicket(UserTicket ticket) {  
        if (canHandler(ticket)) {  
            System.out.println("I can handle this ticket, get solution.");  
            return getSolution(ticket);  
        } else if (nextHandler != null) {  
            System.out.println("I can't handle this ticket, send to next handler.");  
            return nextHandler.handleTicket(ticket);  
        } else {  
            System.out.println("No one can handle this ticket.");  
            return "No answer.";  
        }  
    }  
  
    abstract boolean canHandler(UserTicket ticket);  
  
    abstract String getSolution(UserTicket ticket);  
}

ConcreteHandlers - 具体实现类

// AI客服
public class AiChatBot extends BaseTicketHandler {  
    @Override  
    boolean canHandler(UserTicket ticket) {  
        if (ticket.isEasy()) {  
            System.out.println("It's an easy ticket, ai chat bot can handle it.");  
            return true;  
        }  
        return false;  
    }  
  
    @Override  
    String getSolution(UserTicket ticket) {  
        return "AI chat bots answer.";  
    }  
}

// 人工客服
public class ManualCustomService extends BaseTicketHandler {  
    @Override  
    boolean canHandler(UserTicket ticket) {  
        if (ticket.isMiddle()) {  
            System.out.println("It's a middle ticket, manual custom service can handle it.");  
            return true;  
        }  
        return false;  
    }  
  
    @Override  
    String getSolution(UserTicket ticket) {  
        return "Manual custom services answer.";  
    }  
}

// SRE工程师
public class SreEngineer extends BaseTicketHandler {  
    @Override  
    boolean canHandler(UserTicket ticket) {  
        if (ticket.isHard()) {  
            System.out.println("It's a hard ticket, sre can handle it.");  
            return true;  
        }  
        return false;  
    }  
  
    @Override  
    String getSolution(UserTicket ticket) {  
        return "SRE engineer's answer.";  
    }  
}

// OPS工程师
public class OpsEngineer extends BaseTicketHandler {  
    @Override  
    boolean canHandler(UserTicket ticket) {  
        if (ticket.isCritical()) {  
            System.out.println("It's a critical ticket, must ops handle it.");  
            return true;  
        }  
        return false;  
    }  
  
    @Override  
    String getSolution(UserTicket ticket) {  
        return "Ops engineer's answer.";  
    }  
}

Application

public class UserTicketApplication {  
    private static final BaseTicketHandler handlerChain = getHandlerChain();  
  
    private static BaseTicketHandler getHandlerChain() {  
        BaseTicketHandler ops = new OpsEngineer();  
  
        BaseTicketHandler sre = new SreEngineer();  
        sre.setNextHandler(ops);  
  
        BaseTicketHandler manual = new ManualCustomService();  
        manual.setNextHandler(sre);  
  
        BaseTicketHandler ai = new AiChatBot();  
        ai.setNextHandler(manual);  
  
        return ai;  
    }  
  
    public String handleTicket(UserTicket ticket) {  
        return handlerChain.handleTicket(ticket);  
    }  
  
    public static void main(String[] args) {  
        UserTicketApplication app = new UserTicketApplication();  
  
        UserTicket easy = new UserTicket("easy", "how to create an account?", "iam", 2);  
        System.out.println(app.handleTicket(easy));  
        System.out.println("===");  
  
        UserTicket middle = new UserTicket("middle", "how to create a service demo?", "dli", 5);  
        System.out.println(app.handleTicket(middle));  
        System.out.println("===");  
  
        UserTicket hard = new UserTicket("hard", "how to create a cluster?", "mrs", 8);  
        System.out.println(app.handleTicket(hard));  
        System.out.println("===");  
  
        UserTicket critical = new UserTicket("critical", "my service is crashed!", "obs", 10);  
        System.out.println(app.handleTicket(critical));  
        System.out.println("===");  
  
        UserTicket other = new UserTicket("other", "hahaha", "noknown", 12);  
        System.out.println(app.handleTicket(other));  
    }  
}

数据类

@Data  
@AllArgsConstructor  
public class UserTicket {  
    private String title;  
  
    private String content;  
  
    private String service;  
  
    private int score;  
  
    public boolean isEasy() {  
        return score > 0 && score <= 3;  
    }  
  
    public boolean isMiddle() {  
        return score > 3 && score <= 5;  
    }  
  
    public boolean isHard() {  
        return score > 5 && score <= 8;  
    }  
  
    public boolean isCritical() {  
        return score > 8 && score <= 10;  
    }  
}

结果

It's an easy ticket, ai chat bot can handle it.
I can handle this ticket, get solution.
AI chat bots answer.
===
I can't handle this ticket, send to next handler.
It's a middle ticket, manual custom service can handle it.
I can handle this ticket, get solution.
Manual custom services answer.
===
I can't handle this ticket, send to next handler.
I can't handle this ticket, send to next handler.
It's a hard ticket, sre can handle it.
I can handle this ticket, get solution.
SRE engineer's answer.
===
I can't handle this ticket, send to next handler.
I can't handle this ticket, send to next handler.
I can't handle this ticket, send to next handler.
It's a critical ticket, must ops handle it.
I can handle this ticket, get solution.
Ops engineer's answer.
===
I can't handle this ticket, send to next handler.
I can't handle this ticket, send to next handler.
I can't handle this ticket, send to next handler.
No one can handle this ticket.
No answer.

责任链模式

结构

Pasted image 20230211161920

值得注意的是

适用场景


以上。