当前位置: 首页 > news >正文

沧州网站建设公司中国网新山东

沧州网站建设公司,中国网新山东,企业策划营销中心,网站数据流分析怎么做认识设计模式(十一)---责任链模式【一】责任链模式【二】介绍(1)意图(2)主要解决(3)何时使用(4)如何解决(5)关键代码(6&am…

认识设计模式(十一)---责任链模式

  • 【一】责任链模式
  • 【二】介绍
    • (1)意图
    • (2)主要解决
    • (3)何时使用
    • (4)如何解决
    • (5)关键代码
    • (6)应用实例
    • (7)优点
    • (8)缺点
    • (9)使用场景
    • (10)注意事项
  • 【三】实现案例
    • (1)介绍
    • (2)创建抽象的记录器类
    • (3)创建扩展了该记录器类的实体类
    • (4)创建不同类型的记录器
  • 【四】更多案例介绍
    • (1)责任链模式解决采购审批问题
      • 1-创建采购请求的实体类
      • 2-创建抽象的采购审批类
      • 3-创建扩展了该审批类的实体类
      • 4-设置责任链,测试类
    • (2)责任链模式解决登录过程的数据校验问题
      • 1-创建一个实体类Member
      • 2-传统方式的登录校验代码
      • 3-开始使用责任链模式优化,创建抽象的处理类Handler
      • 4-创建扩展了处理类的实体类
      • 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 type=0;private float price=0.0f;private int id=0;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("请求编号id="+purchaseRequest.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()>5000&&purchaseRequest.getPrice()<=10000){System.out.println("请求编号id="+purchaseRequest.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()>10000&&purchaseRequest.getPrice()<=30000){System.out.println("请求编号id="+purchaseRequest.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("请求编号id="+purchaseRequest.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 purchaseRequest=new PurchaseRequest(1,31000,1);//创建相关的审批人DepartmentApprover departmentApprover=new DepartmentApprover("张主任");CollegeApprover collegeApprover=new CollegeApprover("李院长");ViceSchoolMasterApprover viceSchoolMasterApprover=new ViceSchoolMasterApprover("王副校长");SchoolMasterApprover schoolMasterApprover=new 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 Handler<T> {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 Builder<T>{private Handler<T> head;private Handler<T> tail;public Builder<T> 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 Handler<T> 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的人,肯定见过}
}
http://www.ritt.cn/news/4208.html

相关文章:

  • 学做网站开发要1万6百度云资源共享
  • 公司做网站需要提供的材料seo工资待遇怎么样
  • 电脑怎样做网站线上营销有哪些
  • 网站建设玖金手指排名15南昌seo方案
  • 网站建设需要注意哪些问题企业网站推广模式
  • 网站业务怎么做的我想开个网站平台怎么开呢
  • 松江做网站企业关键词优化公司
  • 如何自己做自己的网站网上做广告宣传
  • 网站专题制作12月30日疫情最新消息
  • 阿里巴巴做网站营销有没有用seo需要会什么
  • 国家疫情防控最新政策文件seo关键词排名价格
  • 网站在线订单系统怎么做seo每日
  • 网站管理助手v3seo发展前景怎么样啊
  • 多语言网站 推广温州免费建站模板
  • 目前流行的网站分辨率做多大赤峰seo
  • 推荐聊城做网站seo还能赚钱吗
  • 跨境电商平台官网河南自助建站seo公司
  • 营销策划方案范文1500江苏网站seo营销模板
  • 全国公共资源交易中心网站及搜索引擎优化建议
  • 一个专门做酒店招聘的网站seo公司赚钱吗
  • 想给公司做个网站怎么做的百度站长工具平台
  • 动态网站用什么语言做图片在线转外链
  • 司法公开网站建设情况汇报长沙免费建站网络营销
  • 网站开发的职责与分工百度搜题网页版入口
  • 政府网站建设管理典型材料新闻稿范文
  • 运输房产网站建设百度客服在线客服入口
  • 东莞企业网站写一篇软文推广自己的学校
  • 做魔方网站用什么背景最好如何推广新产品的方法
  • 外国网站做问卷调查挣钱太原首页推广
  • 视频直播网站如何做360网站安全检测