设计模式之装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)

devtools/2024/11/17 0:55:29/

前言:
两个本想描述一样的意思的词,只因一字只差就让人觉得一个是好牛,一个好搞笑。往往我们去开发编程写代码时也经常将一些不恰当的用法用于业务需求实现中,但却不能意识到。一方面是由于编码不多缺少较大型项目的实践,另一方面是不思进取的总在以完成需求为目标缺少精益求精的工匠精神。
在这里插入图片描述
初看上图感觉装饰器模式有点像俄罗斯套娃、某众汽车🚕,而装饰器的核心就是在不改原有类的基础上给类新增功能。不改变原有类,可能有的小伙伴会想到继承、AOP切面,当然这些方式都可以实现,但是使用装饰器模式会是另外一种思路更为灵活,可以避免继承导致的子类过多,也可以避免AOP带来的复杂性。
在这里插入图片描述
这里模拟的是spring中的类:HandlerInterceptor,实现接口功能SsoInterceptor模拟的单点登录拦截服务。
模拟Spring的HandlerInterceptor

java">package oom.lm.design;public interface HandlerInterceptor {boolean preHandle(String request, String response, Object handler);}

模拟单点登录功能

java">package oom.lm.design;public class SsoInterceptor implements HandlerInterceptor{@Overridepublic boolean preHandle(String request, String response, Object handler) {// 模拟获取cookieString ticket = request.substring(1, 8);// 模拟校验return ticket.equals("success");}}

里的模拟实现非常简单只是截取字符串,实际使用需要从HttpServletRequest request对象中获取cookie信息,解析ticket值做校验
用一坨坨代码实现
继承类的实现方式也是一个比较通用的方式,通过继承后重写方法,并发将自己的逻辑覆盖进去。如果是一些简单的场景且不需要不断维护和扩展的,此类实现并不会有什么,也不会导致子类过多。

java">package oom.lm.design;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;public class LoginSsoDecorator extends SsoInterceptor {private static Map<String, String> authMap = new ConcurrentHashMap<String, String>();static {authMap.put("huahua", "queryUserInfo");authMap.put("doudou", "queryUserInfo");}@Overridepublic boolean preHandle(String request, String response, Object handler) {// 模拟获取cookieString ticket = request.substring(1, 8);// 模拟校验boolean success = ticket.equals("success");if (!success){return false;}String userId = request.substring(9);String method = authMap.get(userId);// 模拟方法校验return "queryUserInfo".equals(method);}}

以上这部分通过继承重写方法,将个人可访问哪些方法的功能添加到方法中。
测试验证

java">package oom.lm.design.test;import oom.lm.design.LoginSsoDecorator;
import org.junit.Test;public class ApiTest {@Testpublic void test_LoginSsoDecorator() {LoginSsoDecorator ssoDecorator = new LoginSsoDecorator();String request = "1successhuahua";boolean success = ssoDecorator.preHandle(request, "ewcdqwt40liuiu", "t");System.out.println("登录校验:" + request + (success ? " 放行" : " 拦截"));}}

装饰器模式重构代码
装饰器主要解决的是直接继承下因功能的不断横向扩展导致子类膨胀的问题,而是用装饰器模式后就会比直接继承显得更加灵活同时这样也就不再需要考虑子类的维护。
1:抽象构件角色(Component) - 定义抽象接口
2:具体构件角色(ConcreteComponent) - 实现抽象接口,可以是一组
3:装饰角色(Decorator) - 定义抽象类并继承接口中的方法,保证一致性
4:具体装饰角色(ConcreteDecorator) - 扩展装饰具体的实现逻辑
在这里插入图片描述
装饰器模式模型结构
在这里插入图片描述
抽象类装饰角色

java">package oom.lm.design;public abstract class SsoDecorator implements HandlerInterceptor {private HandlerInterceptor handlerInterceptor;private SsoDecorator(){}public SsoDecorator(HandlerInterceptor handlerInterceptor) {this.handlerInterceptor = handlerInterceptor;}@Overridepublic boolean preHandle(String request, String response, Object handler) {return handlerInterceptor.preHandle(request, response, handler);}}

在装饰类中有三个重点的地方是:1)继承了处理接口、2)提供了构造函数、3)覆盖了方法preHandle。
装饰角色逻辑实现

java">package oom.lm.design;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;public class LoginSsoDecorator extends SsoDecorator {private Logger logger = LoggerFactory.getLogger(LoginSsoDecorator.class);private static Map<String, String> authMap = new ConcurrentHashMap<String, String>();static {authMap.put("huahua", "queryUserInfo");authMap.put("doudou", "queryUserInfo");}public LoginSsoDecorator(HandlerInterceptor handlerInterceptor) {super(handlerInterceptor);}@Overridepublic boolean preHandle(String request, String response, Object handler) {boolean success = super.preHandle(request, response, handler);if (!success) return false;String userId = request.substring(8);String method = authMap.get(userId);logger.info("模拟单点登录方法访问拦截校验:{} {}", userId, method);// 模拟方法校验return "queryUserInfo".equals(method);}
}

在具体的装饰类实现中,继承了装饰类SsoDecorator,那么现在就可以扩展方法;preHandle
测试验证

java">package oom.lm.design.test;import oom.lm.design.LoginSsoDecorator;
import oom.lm.design.SsoInterceptor;
import org.junit.Test;public class ApiTest {@Testpublic void test_LoginSsoDecorator() {LoginSsoDecorator ssoDecorator = new LoginSsoDecorator(new SsoInterceptor());String request = "1successhuahua";boolean success = ssoDecorator.preHandle(request, "ewcdqwt40liuiu", "t");System.out.println("登录校验:" + request + (success ? " 放行" : " 拦截"));}}

总结
1:使用装饰器模式满足单一职责原则,你可以在自己的装饰类中完成功能逻辑的扩展,而不影响主类,同时可以按需在运行时添加和删除这部分逻辑。另外装饰器模式与继承父类重写方法,在某些时候需要按需选择,并不一定某一个就是最好。
2:装饰器实现的重点是对抽象类继承接口方式的使用,同时设定被继承的接口可以通过构造函数传递其实现类,由此增加扩展性并重写方法里可以实现此部分父类实现的功能。
就像夏天热你穿短裤,冬天冷你穿棉裤,雨天挨浇你穿雨衣一样,你的根本本身没有被改变,而你的3:需求却被不同的装饰而实现。生活中往往比比皆是设计,当你可以融合这部分活灵活现的例子到代码实现中,往往会创造出更加优雅的实现方式。

好了 至此 设计模式装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景) 学习结束了 友友们 点点关注不迷路 老铁们!!!!!


http://www.ppmy.cn/devtools/134579.html

相关文章

flink cdc 应用

SQLServer 1. The db history topic or its content is fully or partially missing. Please check database history topic configuration and re-execute the snapshot. 遇到了一下问题&#xff0c;多次尝试&#xff0c;最终发现是数据库大小写要一致。 Caused by: io.deb…

24/11/14 算法笔记 EM算法期望最大化算法

EM算法用于含有隐变量的概率参数模型的最大似然估计或极大后验概率估计。它在机器学习和统计学中有着广泛的应用&#xff0c;比如在高斯混合模型&#xff08;GMM&#xff09;、隐马尔可夫模型&#xff08;HMM&#xff09;以及各种聚类和分类问题中。 EM算法的基本思想是&#…

如何利用静态住宅IP提升TikTok营销效果:应对平台限制与账号安全的新利器

随着TikTok的全球化和日益严苛的运营政策&#xff0c;越来越多的品牌和商家开始面临着平台地域限制、账户管理及内容推广的挑战。特别是在多个账户管理和跨境营销中&#xff0c;如何避免账号封禁、提高内容曝光&#xff0c;成为了亟待解决的问题。在这种背景下&#xff0c;代理…

STM32 ADC --- DMA乒乓缓存

STM32 ADC — DMA乒乓缓存 文章目录 STM32 ADC --- DMA乒乓缓存软件切换实现乒乓利用DMA双缓冲实现乒乓 通过cubeMX配置生成HAL工程这里使用的是上篇文章&#xff08;STM32 ADC — DMA采样&#xff09;中生成的工程配置 软件切换实现乒乓 cubeMX默认生成的工程中是打开DMA中断…

【python系列】python数据类型之数字类型

1.定义 数字类型是编程中最常用的数据类型。什么是数字类型&#xff0c;下面是数字类型官方文档的解释&#xff1a;https://docs.python.org/zh-cn/3.10/library/stdtypes.html?highlightstr%20join#numeric-types-int-float-complex 以上可以知道&#xff1a; 数字类型包…

回调函数的概念、意义和应用场景

概念 回调函数&#xff0c;就是使用者自己定义一个函数&#xff0c;并实现函数的内容&#xff0c;然后把这个函数作为参数传入其它函数中&#xff0c;由其它函数在运行时来调用。 换句话说&#xff0c;函数是你实现的&#xff0c;但由别人的函数在运行时通过参数传递的方式调用…

flutter下拉刷新上拉加载的简单实现方式三

使用 CustomScrollView 结合 SliverList 实现了一个支持下拉刷新和上拉加载更多功能的滚动列表&#xff0c;对下面代码进行解析学习。 import dart:math;import package:flutter/material.dart;import custom_pull/gsy_refresh_sliver.dart; import package:flutter/cupertino…

hhdb数据库介绍(9-14)

SQL语法支持 DML语句 在关系集群数据库中&#xff0c;DML语句的逻辑将变的更为复杂。计算节点将DML语句分为两大类&#xff1a;单库DML语句与跨库DML语句。 单库DML语句&#xff0c;指SQL语句只需在一个节点上运行&#xff0c;即可计算出正确结果。假设分片表customer分片字…