设计模式之责任链模式

miloyang
0 评论
/ /
435 阅读
/
3057 字
22 2023-11

简介

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它通过一系列处理者(处理对象)来逐步处理请求,直到请求被处理为止。每个处理者都包含了处理请求的逻辑,并且知道下一个处理者是谁。

责任链模式涉及到以下几个主要角色:

  • 处理者(Handler)

    定义了一个处理请求的接口,通常包含一个处理方法,同时包含一个指向下一个处理者的引用。

  • 具体处理者(ConcreteHandler)

    实现了处理者接口,负责处理特定类型的请求。如果自己能够处理,则处理请求,否则将请求传递给下一个处理者。

  • 客户端(Client)

    创建请求,并将请求发送给第一个处理者。

jugelizi

比如今天无论如何要去买车,但是你身上只有那么点钱,根据金额,先去看BWN,再去看BenZ,最后看Mazda,如果前面都没看到合适价位的,你今天就error了。 ps:感觉这个例子不太好,如果改为线上宕机了,损失几个爽,要背锅了,先从总监->组长->运维->你,一路追责下来,这个例子好点。没办法,我就是喜欢车。

Demo

// Handler 处理者接口
type Handler interface {
    HandleRequest(amount int)
    SetSuccessor(successor Handler)
}

// CarHandler 购车处理者,具体处理者
type CarHandler struct {
    Price     int
    Car       string
    successor Handler
}

func (c *CarHandler) HandleRequest(price int) {
    if price >= c.Price {
        fmt.Printf("你的金额为:%d,你可以买 %s\n", price, c.Car)
    } else if c.successor != nil {
        fmt.Printf("你的金额为:%d, 你不能买 %s\n ", price, c.Car)
        fmt.Printf("不过我们可以看看下一个你可以买的车.\n")
        c.successor.HandleRequest(price)
    } else {
        fmt.Printf("Sorry, 你的金额%d,买不了任何车,这边建议你买电动车\n", price)
    }
}

func (c *CarHandler) SetSuccessor(successor Handler) {
    c.successor = successor
}

测试

func TestResponsibilityChain(t *testing.T) {
    // 客户端使用责任链模式
    bmwHandler := &CarHandler{Price: 200000, Car: "BMW"}
    benzHandler := &CarHandler{Price: 150000, Car: "Benz"}
    mazdaHandler := &CarHandler{Price: 100000, Car: "Mazda"}
    noCarHandler := &CarHandler{Price: 0, Car: "no car"}

    // 设置处理者的后继关系
    bmwHandler.SetSuccessor(benzHandler)
    benzHandler.SetSuccessor(mazdaHandler)
    mazdaHandler.SetSuccessor(noCarHandler)

    // 模拟用户输入不同的金额
    amounts := []int{180000, 220000, 120000, 80000}

    for _, amount := range amounts {
        // 通过责任链传递请求
        bmwHandler.HandleRequest(amount)
        fmt.Println("---------------------")
    }
}

在这个示例中,每个 CarHandler 表示一种车的购买条件,包括金额阈值和车型。客户端创建了一条责任链,连接了购买不同车型的处理者。当用户输入不同的金额时,责任链会逐步判断是否满足购车条件,如果不满足,则请求会被传递给下一个处理者。最终,用户会得知根据输入金额能否购买某种车型。

这种设计模式使得条件判断和处理逻辑更具灵活性,可以动态添加或修改购车条件,而不需要修改客户端的代码。

作用和场景

  • 解耦发送者和接收者

    责任链模式可以将请求的发送者和接收者解耦,每个处理者只关心自己能否处理该请求,而不需要知道请求的具体来源和去向。比如我只需要录入金额,然后就分别去判断可以买什么东西。

  • 动态建立责任链

    可以动态地建立责任链,根据实际情况来灵活配置处理者的顺序和组合。这使得系统更具扩展性,可以根据需要动态添加、移除或修改处理者。

  • 支持单一职责原则

    责任链模式可以使得每个处理者只负责一个明确的责任,符合单一职责原则。这样可以使系统更易于理解和维护

当一个请求可以被多个对象处理,但处理者之间具有不同的优先级或处理条件时,可以使用责任链模式。

当发送者和接收者之间不希望直接耦合时,可以使用责任链模式。

当责任链的组成部分需要动态地配置或改变顺序时,责任链模式可以提供灵活性。

当希望每个处理者只负责一个明确的责任,以支持单一职责原则时,可以使用责任链模式。

总体而言,责任链模式适用于多个对象处理同一类型的请求,且请求的处理顺序和条件可能动态变化的情况。

人未眠
工作数十年
脚步未曾歇,学习未曾停
乍回首
路程虽丰富,知识未记录
   借此博客,与之共进步