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.