首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Golang语言情怀-第26期 Go 语言设计模式 职责链

Golang语言情怀-第26期 Go 语言设计模式 职责链

作者头像
李海彬
发布2021-02-05 16:19:47
发布2021-02-05 16:19:47
3820
举报
文章被收录于专栏:Golang语言社区Golang语言社区

1 定义

职责链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

现实生活中有很多类似职责链模式的例子,比如我们在公司请假需要填写电子流给各个领导审批,如果请假时长比较短的时候,你的直属领导就有权力决定是否同意你请假,但是如果时间比较长的话,那就要给更高一层的领导审批了,类似的还有加薪申请也是一样的情况。 其UML类图如下:

UML类图:

实例1

代码语言:javascript
复制
ackage ChainofResponsibilityPattern

const (
    INFO = iota + 1
    DEBUG
    ERROR
)

type Logger interface {
    LogMessage(level int, message string, logger Logger)
    write(message string)
}

type AbstractLogger struct {
    level      int
    nextLogger Logger
}

func (s *AbstractLogger) write(message string) {

}

func (s *AbstractLogger) SetNextLogger(logger Logger) {
    s.nextLogger = logger
}

func (s *AbstractLogger) LogMessage(level int, message string, logger Logger) {
    if s.level <= level {
        logger.write(message)
    } else {
        if s.nextLogger != nil {
            s.nextLogger.LogMessage(level, message, s.nextLogger)
        }
    }
}
代码语言:javascript
复制
package ChainofResponsibilityPattern

import "fmt"

type ConsoleLogger struct {
    abstractLogger AbstractLogger
}

func (c *ConsoleLogger) write(message string) {
    fmt.Println("Standard Console::Logger: " + message)
}

func (c *ConsoleLogger) LogMessage(level int, message string, logger Logger) {
    c.abstractLogger.LogMessage(level, message, c)
}
代码语言:javascript
复制
package ChainofResponsibilityPattern

import "fmt"

type ErrorLogger struct {
    abstractLogger AbstractLogger
}

func (e *ErrorLogger) write(message string) {
    fmt.Println("Error Console::Logger: " + message)
}

func (e *ErrorLogger) LogMessage(level int, message string, logger Logger) {
    e.abstractLogger.LogMessage(level, message, e)
}
代码语言:javascript
复制
package ChainofResponsibilityPattern

import "fmt"

type FileLogger struct {
    abstractLogger AbstractLogger
}

func (f *FileLogger) write(message string) {
    fmt.Println("File::Logger: " + message)
}

func (f *FileLogger) LogMessage(level int, message string, logger Logger) {
    f.abstractLogger.LogMessage(level, message, f)
}
代码语言:javascript
复制
package ChainofResponsibilityPattern

func TestChainofResponsibilityPattern() Logger {
    errorLogger := new(ErrorLogger)
    errorLogger.abstractLogger.level = ERROR

    fileLogger := new(FileLogger)
    fileLogger.abstractLogger.level = DEBUG

    consoleLogger := new(ConsoleLogger)
    consoleLogger.abstractLogger.level = INFO

    errorLogger.abstractLogger.SetNextLogger(fileLogger)
    fileLogger.abstractLogger.SetNextLogger(consoleLogger)

    return errorLogger
}
代码语言:javascript
复制
func testChainofResponsibilityPattern() {
    logger := ChainofResponsibilityPattern.TestChainofResponsibilityPattern()

    logger.LogMessage(ChainofResponsibilityPattern.INFO, "This is an information.", nil)

    logger.LogMessage(ChainofResponsibilityPattern.DEBUG, "This is a debug level information.", nil)

    logger.LogMessage(ChainofResponsibilityPattern.ERROR, "This is an error information.", nil)
}

输出:

代码语言:javascript
复制
Standard Console::Logger: This is an information.
File::Logger: This is a debug level information.
Error Console::Logger: This is an error information.

实例2

代码语言:javascript
复制
package chainofresponsibility

import "fmt"

type Request struct {
    RequestType    string
    RequestContent string
    Number         int
}

type Manager interface {
    SetNext(next Manager)
    RequestHandler(request Request)
}

type CommonManager struct {
    Manager
    Name string
}

func (cm *CommonManager) SetNext(next Manager) {
    cm.Manager = next
}

func (cm *CommonManager) RequestHandler(request Request) {
    if request.RequestType == "请假" && request.Number <= 2 {
        fmt.Printf("%s: %s 数量 %d 已批准\n", cm.Name, request.RequestContent, request.Number)
    } else {
        if cm.Manager != nil {
            cm.Manager.RequestHandler(request)
        }
    }
}

type MajorManager struct {
    Manager
    Name string
}

func (mm *MajorManager) SetNext(next Manager) {
    mm.Manager = next
}

func (mm *MajorManager) RequestHandler(request Request) {
    if request.RequestType == "请假" && request.Number <= 5 {
        fmt.Printf("%s: %s 数量 %d 已批准\n", mm.Name, request.RequestContent, request.Number)
    } else {
        if mm.Manager != nil {
            mm.Manager.RequestHandler(request)
        }
    }
}

type GeneralManager struct {
    Manager
    Name string
}

func (gm *GeneralManager) SetNext(next Manager) {
    gm.Manager = next
}

func (gm *GeneralManager) RequestHandler(request Request) {
    if request.RequestType == "请假" {
        fmt.Printf("%s: %s 数量 %d 已批准\n", gm.Name, request.RequestContent, request.Number)
    } else if request.RequestType == "加薪" && request.Number <= 500 {
        fmt.Printf("%s: %s 数量 %d 已批准\n", gm.Name, request.RequestContent, request.Number)
    } else if request.RequestType == "加薪" && request.Number > 500 {
        fmt.Printf("%s: %s 数量 %d 再说吧\n", gm.Name, request.RequestContent, request.Number)
    }
}

客户端调用:

代码语言:javascript
复制
func main() {
    wenxiang := &chainofresponsibility.CommonManager{
        Name: "文祥",
    }
    xiaoyun := &chainofresponsibility.MajorManager{
        Name: "晓云",
    }
    yuanlei := &chainofresponsibility.GeneralManager{
        Name: "苑磊",
    }
    wenxiang.SetNext(xiaoyun)
    xiaoyun.SetNext(yuanlei)

    request := chainofresponsibility.Request{
        RequestType:    "请假",
        RequestContent: "小菜请假",
        Number:         2,
    }
    wenxiang.RequestHandler(request)

    request = chainofresponsibility.Request{
        RequestType:    "请假",
        RequestContent: "小菜请假",
        Number:         5,
    }
    wenxiang.RequestHandler(request)

    request = chainofresponsibility.Request{
        RequestType:    "加薪",
        RequestContent: "小菜请求加薪",
        Number:         500,
    }
    wenxiang.RequestHandler(request)

    request = chainofresponsibility.Request{
        RequestType:    "加薪",
        RequestContent: "小菜请求加薪",
        Number:         1000,
    }
    wenxiang.RequestHandler(request)
}

参考资料:

Go语言设计模式-职责链

https://blog.csdn.net/weixin_40165163/article/details/90814115

职责链设计模式

https://blog.csdn.net/clouduncle/article/details/84865967

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言情怀 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 定义
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档