2021年7月29日星期四

职责链模式(学习笔记)

  1. 意图

  使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止

  2. 动机

  假设现在开发一个在线订购系统。希望对系统访问进行限制,只允许认证用户创建订单。可是,在接下来的几个月里,不断有新的需求提了出来....

  • 一位同事认为直接将原始数据传递给订购系统存在安全隐患。因此你新增了额外的验证步骤来清洗请求中的数据
  • 后来,有人注意到系统无法抵御暴力密码破解方式的攻击。为了防范这种情况,你立刻添加了一个检查步骤来过滤来自同一IP地址的重复错误请求
  • 再后来,又有人提议可以对包含同样数据的重复请求返回缓存中的结果,从而提高系统响应速度。因此,你新增了一个检查步骤,确保只有没有满足条件的缓存结果时请求才能通过并被发送给系统

  

  检查代码本来就已经混乱不堪,而每次新增功能都会使其更加臃肿。修改某个检查步骤有时会影响其他的检查步骤。系统会变得让人非常费解,而且其维护成本也会激增

  责任链会将特定行为转换为被称作处理者的独立对象。每个检查步骤都可被抽取为仅有单个方法的类,并执行检查操作。请求及其数据则会被作为参数传递给该方法。并且,链上的每个处理者都有一个成员变量来保存对于下一处理者的引用。处理者接收到请求后自行决定是否能够对其进行处理。如果自己能够处理,处理者就不再继续传递请求。否则,请求会在链上移动, 直至所有处理者都有机会对其进行处理。因此在这种情况下,每个请求要么最多有一个处理者对其进行处理,要么没有任何处理者对其进行处理 

  3. 适用性

  • 当程序需要使用不同方式处理不同种类请求,而且请求类型和顺序预先未知时。该模式能将多个处理者连接成一条链。接收到请求后,它会 "询问" 每个处理者是否能够对其进行处理。这样所有处理者都有机会来处理请求
  • 当必须按顺序执行多个处理者时
  • 如果所需处理者及其顺序必须在运行时进行改变

  4. 结构

      

  5. 效果

  1)单一职责原则。 可对发起操作和执行操作的类进行解耦

  2)开闭原则。 可以在不更改现有代码的情况下在程序中新增处理者

  3)增强了给对象指派职责的灵活性

  4)请求可能一直到链的末端都得不到处理

  6. 代码实现

  middleware/Middleware.java: 基础验证接口

package chain_of_responsibility.middleware;/** * @author GaoMing * @date 2021/7/21 - 21:16 */public abstract class Middleware { private Middleware next; /**  * Builds chains of middleware objects.  */ public Middleware linkWith(Middleware next) {  this.next = next;  return next; } /**  * Subclasses will implement this method with concrete checks.  */ public abstract boolean check(String email, String password); /**  * Runs check on the next object in chain or ends traversing if we're in  * last object in chain.  */ protected boolean checkNext(String email, String password) {  if (next == null) {   return true;  }  return next.check(email, password); }}

  middleware/ThrottlingMiddleware.java: 检查请求数量限制

package chain_of_responsibility.middleware;/** * @author GaoMing * @date 2021/7/21 - 21:16 */public class ThrottlingMiddleware extends Middleware{ private int requestPerMinute; private int request; private long currentTime; public ThrottlingMiddleware(int requestPerMinute) {  this.requestPerMinute = requestPerMinute;  this.currentTime = System.currentTimeMillis(); } /**  * Please, not that checkNext() call can be inserted both in the beginning  * of this method and in the end.  *  * This gives much more flexibility than a simple loop over all middleware  * objects. For instance, an element of a chain can change the order of  * checks by running its check after all other checks.  */ public boolean check(String email, String password) {  if (System.currentTimeMillis() > currentTime + 60_000) {   request = 0;   currentTime = System.currentTimeMillis();  }  request++;  if (request > requestPerMinute) {   System.out.println("Request limit exceeded!");   Thread.currentThread().stop();  }  return checkNext(email, password); }}

  middleware/UserExistsMiddleware.java: 检查用户登录信息

package chain_of_responsibility.middleware;import chain_of_responsibility.server.Server;/** * @author GaoMing * @date 2021/7/21 - 21:16 */public class UserExistsMiddleware extends Middleware{ private Server server; public UserExistsMiddleware(Server server) {  this.server = server; } public boolean check(String email, String password) {  if (!server.hasEmail(email)) {   System.out.println("This email is not registered!");   return false;  }  if (!server.isValidPassword(email, password)) {   System.out.println("Wrong password!");   return false;  }  return checkNext(email, password); }}

  middleware/RoleCheckMiddleware.java: 检查用户角色

package chain_of_responsibility.middleware;/** * @author GaoMing * @date 2021/7/21 - 21:17 */public class RockCheckMiddleware extends Middleware{ public boolean check(String email, String password) {  if (email.equals("admin@example.com")) {   System.out.println("Hello, admin!");   return true;  }  System.out.println("Hello, user!");  return checkNext(email, password); }}

  server/Server.java: 授权目标

package chain_of_responsibility.server;import chain_of_responsibility.middleware.Middleware;import java.util.HashMap;import java.util.Map;/** * @author GaoMing * @date 2021/7/21 - 21:22 */public class Server { private Map<String, String> users = new HashMap<>(); private Middleware middleware; /**  * Client passes a chain of object to server. This improves flexibility and  * makes testing the server class easier.  */ public void setMiddleware(Middleware middleware) {  this.middleware = middleware; } /**  * Server gets email and password from client and sends the authorization  * request to the chain.  */ public boolean logIn(String email, String password) {  if (middleware.check(email, password)) {   System.out.println("Authorization have been successful!");   // Do something useful here for authorized users.   return true;  }  return false; } public void register(String email, String password) {  users.put(email, password); } public boolean hasEmail(String email) {  return users.containsKey(email); } public boolean isValidPassword(String email, String password) {  return users.get(email).equals(password); }}

  Demo.java: 客户端代码

package chain_of_responsibility;import chain_of_responsibility.middleware.Middleware;import chain_of_responsibility.middleware.RockCheckMiddleware;import chain_of_responsibility.middleware.ThrottlingMiddleware;import chain_of_responsibility.middleware.UserExistsMiddleware;import chain_of_responsibility.server.Server;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;/** * @author GaoMing * @date 2021/7/21 - 21:15 */public class Demo { private static BufferedReader reader = new BufferedReader(new InputS......

原文转载:http://www.shaoqun.com/a/892286.html

跨境电商:https://www.ikjzd.com/

insider:https://www.ikjzd.com/w/1786

斑马物联网:https://www.ikjzd.com/w/1316

菜鸟网络:https://www.ikjzd.com/w/1547


1.意图  使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止  2.动机  假设现在开发一个在线订购系统。希望对系统访问进行限制,只允许认证用户创建订单。可是,在接下来的几个月里,不断有新的需求提了出来....一位同事认为直接将原始数据传递给订购系统存在安全隐患。因此你新增了额外的验证步骤来清洗请求中的数
f2c:https://www.ikjzd.com/w/1242
四川卧龙暴雨致96人被困 当地疏散游客近11000人:http://www.30bags.com/a/425287.html
四川五一旅游景点推荐 :http://www.30bags.com/a/412760.html
四川西南一带迎新轮强降雨 成都广元等地有暴雨:http://www.30bags.com/a/425276.html
四川乡村旅游春天绚丽绽放 :http://www.30bags.com/a/409518.html
我和合租女人的疯狂偷情故事(5/5):http://lady.shaoqun.com/a/54422.html
换妻游戏没能给我带来难忘的快感(3/3):http://lady.shaoqun.com/m/a/66904.html
情感故事:六年来我睡过的那些女人(11/33):http://lady.shaoqun.com/m/a/68202.html
深圳宝安科技馆8月展览汇总(持续更新):http://www.30bags.com/a/517601.html
2021时尚深圳展蝶讯馆展览好看吗:http://www.30bags.com/a/517602.html
2021时尚深圳蝶讯馆观展攻略:http://www.30bags.com/a/517603.html
深圳欢乐谷夏浪音乐节有朱星杰吗:http://www.30bags.com/a/517604.html

没有评论:

发表评论