Go和Java实现责任链模式

Go和Java实现责任链模式

下面通过一个审批流程的案例来说明责任链模式的使用。

1、责任链模式

责任链模式为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这

种类型的设计模式属于行为型模式。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的

请求传给下一个接收者,依此类推。

  • 意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且

    沿着这条链传递请求,直到有对象处理它为止。

  • 主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细

    节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

  • 何时使用:在处理消息的时候以过滤很多道。

  • 如何解决:拦截的类都实现统一接口。

  • 关键代码:Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向

    谁传递之前 set 进去。

  • 应用实例:1、红楼梦中的"击鼓传花"。 2、JS 中的事件冒泡。 3、JAVA WEB 中 Apache Tomcat 对 Encoding

    的处理,Struts2 的拦截器,jsp servlet 的 Filter。

  • 优点:1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。

    3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责

    任。 4、增加新的请求处理类很方便。

  • 缺点:1、不能保证请求一定被接收。 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能

    会造成循环调用。 3、可能不容易观察运行时的特征,有碍于除错。

  • 使用场景:1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 2、在不明

    确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。

  • 注意事项:在 JAVA WEB 中遇到很多应用。

  • 适用性:

    有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。

    你在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

    可处理一个请求的对象集合应被动态指定。

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一个链,并随着

这条链传递该请求,直到有一个对象处理它为止。这一模式的想法是,给多个对象处理一个请求的机会,从而解耦

发送者和接受者。

2、Go实现责任链模式1

go 复制代码
package chainofresponsibility

// ========== 定义一个处理请求的接口Request ==========
type Request interface {
	Processing()
}
go 复制代码
package chainofresponsibility

import "fmt"

// ========== 离职DimissionRequest ==========
type DimissionRequest struct {
}

func (dimissionRequest *DimissionRequest) Processing() {
	fmt.Println("处理离职!")
}
go 复制代码
package chainofresponsibility

import "fmt"

// ========== 请假LeaveRequest ==========
type LeaveRequest struct {
}

func (LeaveRequest *LeaveRequest) Processing() {
	fmt.Println("处理请假!")
}
go 复制代码
package chainofresponsibility

import "fmt"

// ========== 加薪AddMoneyRequest ==========
type AddMoneyRequest struct {
}

func (addMoneyRequest *AddMoneyRequest) Processing() {
	fmt.Println("处理加薪!")
}
go 复制代码
package chainofresponsibility

// 处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理请求,否则将该请求转发给它的后继者
// ========== RequestHandle ==========
type RequestHandle interface {
	HandleRequests(Request)
	Next(RequestHandle)
}
go 复制代码
package chainofresponsibility

import "fmt"

// ========== HRRequestHandle ==========
type HRRequestHandle struct {
	requestHandle RequestHandle
}

func (hRRequestHandle *HRRequestHandle) HandleRequests(request Request) {
	if req, ok := request.(*DimissionRequest); ok {
		fmt.Println("要离职,人事审批!")
		req.Processing()
	}
	fmt.Println("请求完成!")
}

func (hRRequestHandle *HRRequestHandle) Next(requestHandle RequestHandle) {
	hRRequestHandle.requestHandle = requestHandle
}
go 复制代码
package chainofresponsibility

import "fmt"

// ========== PMRequestHandle ==========
type PMRequestHandle struct {
	requestHandle RequestHandle
}

func (pMRequestHandle *PMRequestHandle) HandleRequests(request Request) {
	if req, ok := request.(*AddMoneyRequest); ok {
		fmt.Println("要加薪,项目经理审批!")
		req.Processing()
	} else {
		pMRequestHandle.requestHandle.HandleRequests(request)
	}
}

func (pMRequestHandle *PMRequestHandle) Next(requestHandle RequestHandle) {
	pMRequestHandle.requestHandle = requestHandle
}
go 复制代码
package chainofresponsibility

import "fmt"

// ========== TLRequestHandle ==========
type TLRequestHandle struct {
	requestHandle RequestHandle
}

func (tLRequestHandle *TLRequestHandle) HandleRequests(request Request) {
	if req, ok := request.(*LeaveRequest); ok {
		fmt.Println("要请假,项目组长审批!")
		req.Processing()
	} else {
		tLRequestHandle.requestHandle.HandleRequests(request)
	}
}

func (tLRequestHandle *TLRequestHandle) Next(requestHandle RequestHandle) {
	tLRequestHandle.requestHandle = requestHandle
}
go 复制代码
package main

import (
	"fmt"
	. "proj/chainofresponsibility"
)

func main() {
	hr := HRRequestHandle{}
	pm := PMRequestHandle{}
	tl := TLRequestHandle{}

	tl.Next(&pm)
	pm.Next(&hr)

	fmt.Println("===========")
	// 人事处理离职请求
	tl.HandleRequests(&DimissionRequest{})

	fmt.Println("===========")
	// 项目经理处理加薪请求
	tl.HandleRequests(&AddMoneyRequest{})

	fmt.Println("========")
	// 组长处理请假请求
	tl.HandleRequests(&LeaveRequest{})
}
shell 复制代码
# 程序输出
===========
要离职,人事审批!
处理离职!
请求完成!
===========
要加薪,项目经理审批!
处理加薪!
========
要请假,项目组长审批!

3、Java实现责任链模式1

java 复制代码
package com.chainofresponsibility;

// ========== 定义一个处理请求的接口Request ==========
public interface Request {
    void processing();
}
java 复制代码
package com.chainofresponsibility;

// ========== 请假LeaveRequest ==========
public class LeaveRequest implements Request{
    @Override
    public void processing() {
        System.out.println("处理请假!");
    }
}
java 复制代码
package com.chainofresponsibility;

// ========== 加薪AddMoneyRequest ==========
public class AddMoneyRequest implements Request {
    @Override
    public void processing() {
        System.out.println("处理加薪!");
    }
}
java 复制代码
package com.chainofresponsibility;

// ========== 离职DimissionRequest ==========
public class DimissionRequest implements Request{
    @Override
    public void processing() {
        System.out.println("处理离职!");
    }
}
java 复制代码
package com.chainofresponsibility;

// 处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理请求,否则将该请求转发给它的后继者
// ========== RequestHandle ==========
public abstract class RequestHandle {
    RequestHandle requestHandle;
    abstract void handleRequest(Request request);
    void next(RequestHandle requestHandle){
        this.requestHandle = requestHandle;
    }
}
java 复制代码
package com.chainofresponsibility;

// ========== HRRequestHandle ==========
public class HRRequestHandle extends RequestHandle {

    @Override
    public void handleRequest(Request request) {
        if (request instanceof DimissionRequest) {
            System.out.println("要离职,人事审批!");
            request.processing();
        }
        System.out.println("请求完成");
    }
}
java 复制代码
package com.chainofresponsibility;

// ========== PMRequestHandle ==========
public class PMRequestHandle extends RequestHandle {

    @Override
    public void handleRequest(Request request) {
        if (request instanceof AddMoneyRequest) {
            System.out.println("要加薪,项目经理审批!");
            request.processing();
        } else {
            requestHandle.handleRequest(request);
        }
    }
}
java 复制代码
package com.chainofresponsibility;

public class TLRequestHandle extends RequestHandle {

    @Override
    public void handleRequest(Request request) {
        if (request instanceof LeaveRequest) {
            System.out.println("要请假,项目组长审批!");
            request.processing();
        } else {
            requestHandle.handleRequest(request);
        }
    }
}
java 复制代码
package com.chainofresponsibility;

public class Test {

    public static void main(String[] args) {

        RequestHandle hr = new HRRequestHandle();
        RequestHandle pm = new PMRequestHandle();
        RequestHandle tl = new TLRequestHandle();

        tl.next(pm);
        pm.next(hr);

        System.out.println("===========");
        // 人事处理离职请求
        Request request = new DimissionRequest();
        tl.handleRequest(request);

        System.out.println("===========");
        // 项目经理处理加薪请求
        request = new AddMoneyRequest();
        tl.handleRequest(request);

        System.out.println("========");
        // 组长处理请假请求
        request = new LeaveRequest();
        tl.handleRequest(request);
    }
}
shell 复制代码
# 程序输出
===========
要离职,人事审批!
处理离职!
请求完成
===========
要加薪,项目经理审批!
处理加薪!
========
要请假,项目组长审批!
处理请假!

4、Go实现责任链模式2

创建 AbstractLogger,带有详细的日志记录级别,然后我们创建三种类型的记录器,都扩展了AbstractLogger。

每个记录器消息的级别是否属于自己的级别,如果是则相应打印出来,否则将消息传递给下一个记录器。

go 复制代码
package chainofresponsibility

// ========== Logger ==========
type Logger interface {
	LogMessage(level int, message string, logger Logger)
	Write(message string)
}
go 复制代码
package chainofresponsibility

// ========== AbstractLogger ==========
type AbstractLogger struct {
	Level      int
	NextLogger Logger
}

func (s *AbstractLogger) Write(message string) {
}

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)
		}
	}
}

func (s *AbstractLogger) SetNextLogger(logger Logger) {
	s.NextLogger = logger
}
go 复制代码
package chainofresponsibility

import "fmt"

// ========== FileLogger ==========
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)
}
go 复制代码
package chainofresponsibility

import "fmt"

// ========== ConsoleLogger ==========
type ConsoleLogger struct {
	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)
}
go 复制代码
package chainofresponsibility

import "fmt"

// ========== ErrorLogger ==========
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)
}
go 复制代码
package constant

const (
	DEBUG = iota + 1
	INFO
	ERROR
)
go 复制代码
package main

import (
	. "proj/chainofresponsibility"
	. "proj/constant"
)

func main() {

	fileLogger := new(FileLogger)
	fileLogger.AbstractLogger.Level = DEBUG

	consoleLogger := new(ConsoleLogger)
	consoleLogger.AbstractLogger.Level = INFO

	errorLogger := new(ErrorLogger)
	errorLogger.AbstractLogger.Level = ERROR

	errorLogger.AbstractLogger.SetNextLogger(consoleLogger)
	consoleLogger.AbstractLogger.SetNextLogger(fileLogger)

	errorLogger.LogMessage(DEBUG, "This is a debug level information.", nil)
	errorLogger.LogMessage(INFO, "This is an info level information.", nil)
	errorLogger.LogMessage(ERROR, "This is an error level information.", nil)

}
shell 复制代码
# 程序输出
File::Logger: This is a debug level information.
Standard Console::Logger: This is an info level information.
Error Console::Logger: This is an error level information.

5、Java实现责任链模式2

java 复制代码
package com.chainofresponsibility;

// ========== AbstractLogger ==========
public abstract class AbstractLogger {

    protected int level;

    // 责任链中的下一个元素
    protected AbstractLogger nextLogger;

    public void setLevel(int level) {
        this.level = level;
    }

    public void setNextLogger(AbstractLogger nextLogger) {
        this.nextLogger = nextLogger;
    }

    public void logMessage(int level, String message) {
        if (this.level <= level) {
            write(message);
        }else{
           if(nextLogger != null) {
               nextLogger.logMessage(level, message);
           }
        }
    }

    abstract protected void write(String message);
}
java 复制代码
package com.chainofresponsibility;

// ========== FileLogger ==========
public class FileLogger extends AbstractLogger {

    @Override
    protected void write(String message) {
        System.out.println("File::Logger: " + message);
    }
}
java 复制代码
package com.chainofresponsibility;

// ========== ConsoleLogger ==========
public class ConsoleLogger extends AbstractLogger {

    @Override
    protected void write(String message) {
        System.out.println("Standard Console::Logger: " + message);
    }
}
java 复制代码
package com.chainofresponsibility;

// ========== ErrorLogger ==========
public class ErrorLogger extends AbstractLogger {

    @Override
    protected void write(String message) {
        System.out.println("Error Console::Logger: " + message);
    }
}
java 复制代码
package com.chainofresponsibility;

public class Constant {
    public static int DEBUG = 1;
    public static int INFO = 2;
    public static int ERROR = 3;
}
java 复制代码
package com.chainofresponsibility;

public class Test {

    public static void main(String[] args) {

        AbstractLogger fileLogger = new FileLogger();
        fileLogger.setLevel(Constant.DEBUG);

        AbstractLogger consoleLogger = new ConsoleLogger();
        consoleLogger.setLevel(Constant.INFO);

        AbstractLogger errorLogger = new ErrorLogger();
        errorLogger.setLevel(Constant.ERROR);

        errorLogger.setNextLogger(consoleLogger);
        consoleLogger.setNextLogger(fileLogger);

        errorLogger.logMessage(Constant.DEBUG, "This is a debug level information.");
        errorLogger.logMessage(Constant.INFO, "This is an info level information.");
        errorLogger.logMessage(Constant.ERROR, "This is an error level information.");
    }
}
shell 复制代码
# 程序输出
File::Logger: This is a debug level information.
Standard Console::Logger: This is an info level information.
Error Console::Logger: This is an error level information.
相关推荐
xiaocaibao77722 分钟前
编程语言的软件工程
开发语言·后端·golang
天天打码25 分钟前
ThinkPHP项目如何关闭runtime下Log日志文件记录
android·java·javascript
捕鲸叉31 分钟前
C++软件设计模式之类型模式和对象型模式
开发语言·c++·设计模式
魔道不误砍柴功32 分钟前
Java 中反射的高级用法:窥探 Java 世界的魔法之门
java·开发语言·python
P7进阶路43 分钟前
实现用户登录系统的前后端开发
java
2401_8576176244 分钟前
“无缝购物体验”:跨平台网上购物商城的设计与实现
java·开发语言·前端·安全·架构·php
事业运财运爆棚1 小时前
7种server的服务器处理结构模型
java·linux·服务器
诸葛悠闲1 小时前
设计模式——组合模式
设计模式·组合模式
诸葛悠闲1 小时前
设计模式——装饰模式
设计模式
西岭千秋雪_1 小时前
设计模式の中介者&发布订阅&备忘录模式
java·观察者模式·设计模式·中介者模式·备忘录模式