职责链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
现实生活中有很多类似职责链模式的例子,比如我们在公司请假需要填写电子流给各个领导审批,如果请假时长比较短的时候,你的直属领导就有权力决定是否同意你请假,但是如果时间比较长的话,那就要给更高一层的领导审批了,类似的还有加薪申请也是一样的情况。 其UML类图如下:
UML类图:

实例1
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)
}
}
}
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)
}
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)
}
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)
}
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
}
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)
}
输出:
Standard Console::Logger: This is an information.
File::Logger: This is a debug level information.
Error Console::Logger: This is an error information.
实例2
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)
}
}
客户端调用:
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