net的网站建设,网站上的图标用什么软件做的,公司建设网站价格表,巩义网络建设网站认识设计模式#xff08;十一#xff09;---责任链模式【一】责任链模式【二】介绍#xff08;1#xff09;意图#xff08;2#xff09;主要解决#xff08;3#xff09;何时使用#xff08;4#xff09;如何解决#xff08;5#xff09;关键代码#xff08;6十一---责任链模式【一】责任链模式【二】介绍1意图2主要解决3何时使用4如何解决5关键代码6应用实例7优点8缺点9使用场景10注意事项【三】实现案例1介绍2创建抽象的记录器类3创建扩展了该记录器类的实体类4创建不同类型的记录器【四】更多案例介绍1责任链模式解决采购审批问题1-创建采购请求的实体类2-创建抽象的采购审批类3-创建扩展了该审批类的实体类4-设置责任链测试类2责任链模式解决登录过程的数据校验问题1-创建一个实体类Member2-传统方式的登录校验代码3-开始使用责任链模式优化创建抽象的处理类Handler4-创建扩展了处理类的实体类5-在服务层设置链6-测试代码7-责任链模式建造者模式结合使用优化【一】责任链模式
顾名思义责任链模式Chain of Responsibility Pattern为请求创建了一个接收者对象的链。这种模式给予请求的类型对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求那么它会把相同的请求传给下一个接收者依此类推。
【二】介绍
1意图
避免请求发送者与接收者耦合在一起让多个对象都有可能接收请求将这些对象连接成一条链并且沿着这条链传递请求直到有对象处理它为止。
2主要解决
职责链上的处理者负责处理请求客户只需要将请求发送到职责链上即可无须关心请求的处理细节和请求的传递所以职责链将请求的发送者和请求的处理者解耦了。
3何时使用
在处理消息的时候以过滤很多道。
4如何解决
拦截的类都实现统一接口。
5关键代码
Handler 里面聚合它自己在 HandlerRequest 里判断是否合适如果没达到条件则向下传递向谁传递之前 set 进去。
6应用实例
1、红楼梦中的击鼓传花。 2、JS 中的事件冒泡。 3、JAVA WEB 中 Apache Tomcat 对 Encoding 的处理Struts2 的拦截器jsp servlet 的 Filter。
7优点
1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。
8缺点
1、不能保证请求一定被接收。 2、系统性能将受到一定影响而且在进行代码调试时不太方便可能会造成循环调用。 3、可能不容易观察运行时的特征有碍于除错。
9使用场景
1、有多个对象可以处理同一个请求具体哪个对象处理该请求由运行时刻自动确定。 2、在不明确指定接收者的情况下向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。
10注意事项
在 JAVA WEB 中遇到很多应用。
【三】实现案例
1介绍
我们创建抽象类 AbstractLogger带有详细的日志记录级别。然后我们创建三种类型的记录器都扩展了 AbstractLogger。每个记录器消息的级别是否属于自己的级别如果是则相应地打印出来否则将不打印并把消息传给下一个记录器。
2创建抽象的记录器类 public abstract class AbstractLogger {public static int INFO 1;public static int DEBUG 2;public static int ERROR 3;protected int level;//责任链中的下一个元素protected AbstractLogger nextLogger;public void setNextLogger(AbstractLogger nextLogger){this.nextLogger nextLogger;}public void logMessage(int level, String message){// 如果传的参数level大于等于已有的level则写日志if(this.level level){write(message);}// 如果下一个记录器不为nullif(nextLogger !null){nextLogger.logMessage(level, message);}}abstract protected void write(String message);}3创建扩展了该记录器类的实体类
public class ConsoleLogger extends AbstractLogger {public ConsoleLogger(int level){this.level level;}Overrideprotected void write(String message) { System.out.println(Standard Console::Logger: message);}
}public class ErrorLogger extends AbstractLogger {public ErrorLogger(int level){this.level level;}Overrideprotected void write(String message) { System.out.println(Error Console::Logger: message);}
}public class FileLogger extends AbstractLogger {public FileLogger(int level){this.level level;}Overrideprotected void write(String message) { System.out.println(File::Logger: message);}
}4创建不同类型的记录器
创建不同类型的记录器。赋予它们不同的错误级别并在每个记录器中设置下一个记录器。每个记录器中的下一个记录器代表的是链的一部分。 public class ChainPatternDemo {private static AbstractLogger getChainOfLoggers(){AbstractLogger errorLogger new ErrorLogger(AbstractLogger.ERROR);AbstractLogger fileLogger new FileLogger(AbstractLogger.DEBUG);AbstractLogger consoleLogger new ConsoleLogger(AbstractLogger.INFO);errorLogger.setNextLogger(fileLogger);fileLogger.setNextLogger(consoleLogger);return errorLogger; }public static void main(String[] args) {AbstractLogger loggerChain getChainOfLoggers();loggerChain.logMessage(AbstractLogger.INFO, This is an information.);loggerChain.logMessage(AbstractLogger.DEBUG, This is a debug level information.);loggerChain.logMessage(AbstractLogger.ERROR, This is an error information.);}
}输出结果
Standard Console::Logger: This is an information.
File::Logger: This is a debug level information.
Standard Console::Logger: This is a debug level information.
Error Console::Logger: This is an error information.
File::Logger: This is an error information.
Standard Console::Logger: This is an error information.【四】更多案例介绍
1责任链模式解决采购审批问题
1-创建采购请求的实体类
/*** ClassName: PurchaseRequest* Author: AllenSun* Date: 2020/3/9 22:36*/
public class PurchaseRequest {private int type0;private float price0.0f;private int id0;public PurchaseRequest(int type, float price, int id) {this.type type;this.price price;this.id id;}public int getType() {return type;}public float getPrice() {return price;}public int getId() {return id;}
}2-创建抽象的采购审批类
/*** ClassName: Approver* Author: AllenSun* Date: 2020/3/9 22:31*/
public abstract class Approver {//下一个处理者Approver approver;//名字String name;public Approver(String name) {this.name name;}//下一个处理者public void setApprover(Approver approver) {this.approver approver;}//处理审批请求的方法得到一个请求处理是子类完成因此该方法做成抽象public abstract void processRequest(PurchaseRequest purchaseRequest);
}3-创建扩展了该审批类的实体类
/*** ClassName: CollegeApprover* Author: AllenSun* Date: 2020/3/9 22:34*/
public class DepartmentApprover extends Approver {public DepartmentApprover(String name) {super(name);}Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if(purchaseRequest.getPrice()5000){System.out.println(请求编号idpurchaseRequest.getId()被this.name处理);} else {approver.processRequest(purchaseRequest);}}
}/*** ClassName: CollegeApprover* Author: AllenSun* Date: 2020/3/9 22:34*/
public class CollegeApprover extends Approver {public CollegeApprover(String name) {super(name);}Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if(purchaseRequest.getPrice()5000purchaseRequest.getPrice()10000){System.out.println(请求编号idpurchaseRequest.getId()被this.name处理);} else {approver.processRequest(purchaseRequest);}}
}/*** ClassName: CollegeApprover* Author: AllenSun* Date: 2020/3/9 22:34*/
public class ViceSchoolMasterApprover extends Approver {public ViceSchoolMasterApprover(String name) {super(name);}Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if(purchaseRequest.getPrice()10000purchaseRequest.getPrice()30000){System.out.println(请求编号idpurchaseRequest.getId()被this.name处理);} else {approver.processRequest(purchaseRequest);}}
}/*** ClassName: CollegeApprover* Author: AllenSun* Date: 2020/3/9 22:34*/
public class SchoolMasterApprover extends Approver {public SchoolMasterApprover(String name) {super(name);}Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if(purchaseRequest.getPrice()30000){System.out.println(请求编号idpurchaseRequest.getId()被this.name处理);} else {approver.processRequest(purchaseRequest);}}
}4-设置责任链测试类
/*** ClassName: Client* Author: AllenSun* Date: 2020/3/9 22:50*/
public class Client {public static void main(String[] args) {//创建一个请求PurchaseRequest purchaseRequestnew PurchaseRequest(1,31000,1);//创建相关的审批人DepartmentApprover departmentApprovernew DepartmentApprover(张主任);CollegeApprover collegeApprovernew CollegeApprover(李院长);ViceSchoolMasterApprover viceSchoolMasterApprovernew ViceSchoolMasterApprover(王副校长);SchoolMasterApprover schoolMasterApprovernew SchoolMasterApprover(孙校长);//需要把各个审批级别的下一个设置好处理人构成环形departmentApprover.setApprover(collegeApprover);collegeApprover.setApprover(viceSchoolMasterApprover);viceSchoolMasterApprover.setApprover(schoolMasterApprover);schoolMasterApprover.setApprover(departmentApprover);departmentApprover.processRequest(purchaseRequest);viceSchoolMasterApprover.processRequest(purchaseRequest);}
}2责任链模式解决登录过程的数据校验问题
在日常生活中责任链模式还是比较常见的我们平时工作处理一些事务往往是各部门协同合作的完成—个任务。而每个部门都有各自的职责因此很多时候事谓完成—半便会转交给下—个部门直到所有部门都过一渔之后事谓才能完成。
1-创建一个实体类Member
Data
public class Member {private String loginName;private String loginPass;private String roleName;public Member(String loginName, String loginPass) {this.loginName loginName;this.loginPass loginPass;}
}2-传统方式的登录校验代码
public class MemberService {public static void main(String[] args) {MemberService service new MemberService();service.login(tom, 666);}public void login(String loginName, String loginPass) {if (StringUtils.isEmpty(loginName) ||StringUtils.isEmpty(loginPass)) {System.out.println(用户名和密码为空);return;}System.out.println(用户名和密码不为空可以往下执行);Member member checkExists(loginName, loginPass);if (null member) {System.out.println(用户不存在);return;}System.out.println(登录成功);if (!管理员.equals(member.getRoleName())) {System.out.println(您不是管理员没有操作权限);return;}System.out.println(允许操作);}private Member checkExists(String loginName, String loginPass) {Member member new Member(loginName, loginPass);member.setRoleName(管理员);return member;}
}3-开始使用责任链模式优化创建抽象的处理类Handler
public abstract class Handler {protected Handler next;public void next(Handler next){ this.next next;}public abstract void doHandler(Member member);
}4-创建扩展了处理类的实体类
我们分别创建非空校验ValidateHandler类、登录校验LoginHandler类和权限校验AuthHandler类
public class ValidateHandler extends Handler {public void doHandler(Member member) {if (StringUtils.isEmpty(member.getLoginName()) ||StringUtils.isEmpty(member.getLoginPass())) {System.out.println(用户名和密码为空);return;}System.out.println(用户名和密码不为空可以往下执行);next.doHandler(member);}
}public class LoginHandler extends Handler {public void doHandler(Member member) {System.out.println(登录成功);member.setRoleName(管理员);next.doHandler(member);}
}public class AuthHandler extends Handler {public void doHandler(Member member) {if (!管理员.equals(member.getRoleName())) {System.out.println(您不是管理员没有操作权限);return;}System.out.println(允许操作);}
}5-在服务层设置链
public class MemberService {public void login(String loginName, String loginPass) {Handler validateHandler new ValidateHandler();Handler loginHandler new LoginHandler();Handler authHandler new AuthHandler();validateHandler.next(loginHandler);loginHandler.next(authHandler);validateHandler.doHandler(new Member(loginName, loginPass));}
}6-测试代码
public class Test {public static void main(String[] args) {MemberService memberService new MemberService();memberService.login(tom,666);}
}测试结果
用户名和密码校验成功可以往下执行
登录成功!
您是管理员允许操作7-责任链模式建造者模式结合使用优化
因为责任链模式具备链式结构而上面代码中我们看到负责组装链式结构的角色是 MemberService ,当链式结构较长时,MemberService的工作会非常繁琐,并且MemberService代码相对臃肿且后续更改处理者或消息类型时都必须在MemberService中进行修改,不符合开闭原则。产生这些问题的原因就是因为链式结构的组装过于复杂,而对于复杂结构的创建很自然我们就会想到建造者模式,使用建造者模式我们完全可以MemberService指定的处理节点对象进行自动链式组装客户只需指定处理节点对象其他任何事情都无需关心并且客户指定的处理节点对象顺序不同 构造出来的链式结构也随之不同。我们来改造一下修改Handler的代码
public abstract class HandlerT {protected Handler next;//public void next(Handler next){ this.next next;}private void next(Handler next){ this.next next;}public abstract void doHandler(Member member);public static class BuilderT{private HandlerT head;private HandlerT tail;public BuilderT addHandler(Handler handler){// do {if (this.head null) {this.head this.tail handler;return this;}this.tail.next(handler);this.tail handler;// }while (false);//真正框架中如果是双向链表会判断是否已经到了尾部return this;}public HandlerT build(){return this.head;}}
}然后 修改MemberService的代码
public class MemberService {public void login(String loginName,String loginPass){Handler.Builder builder new Handler.Builder();builder.addHandler(new ValidateHandler()).addHandler(new LoginHandler()).addHandler(new AuthHandler());builder.build().doHandler(new Member(loginName,loginPass));//用过Netty的人肯定见过}
}