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
package chainofresponsibility// ========== 定义一个处理请求的接口Request ==========
type Request interface {Processing()
}
package chainofresponsibilityimport "fmt"// ========== 离职DimissionRequest ==========
type DimissionRequest struct {
}func (dimissionRequest *DimissionRequest) Processing() {fmt.Println("处理离职!")
}
package chainofresponsibilityimport "fmt"// ========== 请假LeaveRequest ==========
type LeaveRequest struct {
}func (LeaveRequest *LeaveRequest) Processing() {fmt.Println("处理请假!")
}
package chainofresponsibilityimport "fmt"// ========== 加薪AddMoneyRequest ==========
type AddMoneyRequest struct {
}func (addMoneyRequest *AddMoneyRequest) Processing() {fmt.Println("处理加薪!")
}
package chainofresponsibility// 处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理请求,否则将该请求转发给它的后继者
// ========== RequestHandle ==========
type RequestHandle interface {HandleRequests(Request)Next(RequestHandle)
}
package chainofresponsibilityimport "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
}
package chainofresponsibilityimport "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
}
package chainofresponsibilityimport "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
}
package mainimport ("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{})
}
# 程序输出
===========
要离职,人事审批!
处理离职!
请求完成!
===========
要加薪,项目经理审批!
处理加薪!
========
要请假,项目组长审批!
3、Java实现责任链模式1
package com.chainofresponsibility;// ========== 定义一个处理请求的接口Request ==========
public interface Request {void processing();
}
package com.chainofresponsibility;// ========== 请假LeaveRequest ==========
public class LeaveRequest implements Request{@Overridepublic void processing() {System.out.println("处理请假!");}
}
package com.chainofresponsibility;// ========== 加薪AddMoneyRequest ==========
public class AddMoneyRequest implements Request {@Overridepublic void processing() {System.out.println("处理加薪!");}
}
package com.chainofresponsibility;// ========== 离职DimissionRequest ==========
public class DimissionRequest implements Request{@Overridepublic void processing() {System.out.println("处理离职!");}
}
package com.chainofresponsibility;// 处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理请求,否则将该请求转发给它的后继者
// ========== RequestHandle ==========
public abstract class RequestHandle {RequestHandle requestHandle;abstract void handleRequest(Request request);void next(RequestHandle requestHandle){this.requestHandle = requestHandle;}
}
package com.chainofresponsibility;// ========== HRRequestHandle ==========
public class HRRequestHandle extends RequestHandle {@Overridepublic void handleRequest(Request request) {if (request instanceof DimissionRequest) {System.out.println("要离职,人事审批!");request.processing();}System.out.println("请求完成");}
}
package com.chainofresponsibility;// ========== PMRequestHandle ==========
public class PMRequestHandle extends RequestHandle {@Overridepublic void handleRequest(Request request) {if (request instanceof AddMoneyRequest) {System.out.println("要加薪,项目经理审批!");request.processing();} else {requestHandle.handleRequest(request);}}
}
package com.chainofresponsibility;public class TLRequestHandle extends RequestHandle {@Overridepublic void handleRequest(Request request) {if (request instanceof LeaveRequest) {System.out.println("要请假,项目组长审批!");request.processing();} else {requestHandle.handleRequest(request);}}
}
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);}
}
# 程序输出
===========
要离职,人事审批!
处理离职!
请求完成
===========
要加薪,项目经理审批!
处理加薪!
========
要请假,项目组长审批!
处理请假!
4、Go实现责任链模式2
创建 AbstractLogger,带有详细的日志记录级别,然后我们创建三种类型的记录器,都扩展了AbstractLogger。
每个记录器消息的级别是否属于自己的级别,如果是则相应打印出来,否则将消息传递给下一个记录器。
package chainofresponsibility// ========== Logger ==========
type Logger interface {LogMessage(level int, message string, logger Logger)Write(message string)
}
package chainofresponsibility// ========== AbstractLogger ==========
type AbstractLogger struct {Level intNextLogger 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
}
package chainofresponsibilityimport "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)
}
package chainofresponsibilityimport "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)
}
package chainofresponsibilityimport "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)
}
package constantconst (DEBUG = iota + 1INFOERROR
)
package mainimport (. "proj/chainofresponsibility". "proj/constant"
)func main() {fileLogger := new(FileLogger)fileLogger.AbstractLogger.Level = DEBUGconsoleLogger := new(ConsoleLogger)consoleLogger.AbstractLogger.Level = INFOerrorLogger := new(ErrorLogger)errorLogger.AbstractLogger.Level = ERRORerrorLogger.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)}
# 程序输出
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
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);
}
package com.chainofresponsibility;// ========== FileLogger ==========
public class FileLogger extends AbstractLogger {@Overrideprotected void write(String message) {System.out.println("File::Logger: " + message);}
}
package com.chainofresponsibility;// ========== ConsoleLogger ==========
public class ConsoleLogger extends AbstractLogger {@Overrideprotected void write(String message) {System.out.println("Standard Console::Logger: " + message);}
}
package com.chainofresponsibility;// ========== ErrorLogger ==========
public class ErrorLogger extends AbstractLogger {@Overrideprotected void write(String message) {System.out.println("Error Console::Logger: " + message);}
}
package com.chainofresponsibility;public class Constant {public static int DEBUG = 1;public static int INFO = 2;public static int ERROR = 3;
}
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.");}
}
# 程序输出
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.