责任链vs金融登录
金融app相对普通app而言,出于安全考虑,其安全校验方式比较多,以某些银行app为例,手机号登录成功后,会增加指纹、手势、OCR人脸等验证!这些安全项的校验,会根据用户的风险等级有不同的校验优先级,例如A客户的校验顺序是先指纹->手势->OCR,B客户的校验顺序可能是先手势->OCR,其验证顺序不固定,故此处用责任链的模式来设计更为合理:
demo地址:https://download.csdn.net/download/denggun12345/88104411?spm=1001.2014.3001.5503
//基类BusinessObject
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class BusinessObject;
typedef void(^CompletionBlock)(BOOL handled);
typedef void(^ResultBlock)(BusinessObject *handler, BOOL handled);
@interface BusinessObject : NSObject
@property (nonatomic,strong) UILabel *LB;
//下一个响应者
@property (nonatomic,strong) BusinessObject *nextBusiness;
//响应者的处理方法
-(void)handle:(ResultBlock)result;
//各个业务在该方法当中做时机业务处理
-(void)handleBusiness:(CompletionBlock)completion;
@end
NS_ASSUME_NONNULL_END
#import "BusinessObject.h"
@implementation BusinessObject
//责任链入口方法
-(void)handle:(ResultBlock)result{
CompletionBlock completion = ^(BOOL handled){
//当前业务处理掉了,上抛结果
if(handled){
result(self,handled);
}else{
//沿着责任链,指派给下一个业务处理
if(self.nextBusiness){
[self.nextBusiness handle:result];
}else{
//没有业务处理,上抛
result(nil,NO);
}
}
};
//当前业务进行处理
[self handleBusiness:completion];
}
-(void)handleBusiness:(CompletionBlock)completion{
//业务逻辑处理
//如不网络请求、本地照片查询等
}
@end
模拟业务类,即继承基类的类,用来模拟指纹、手势、ocr的业务类
#import "BusinessObjectA.h"
@implementation BusinessObjectA
-(void)handleBusiness:(CompletionBlock)completion{
NSLog(@"BusinessObjectA");
if ([self.LB.text isEqualToString:@"0"]) {
completion(YES);
}else{
completion(NO);
}
}
@end
#import "BusinessObjectB.h"
@implementation BusinessObjectB
-(void)handleBusiness:(CompletionBlock)completion{
NSLog(@"BusinessObjectB");
if ([self.LB.text isEqualToString:@"0"]) {
completion(YES);
}else{
completion(NO);
}
}
@end
#import "BusinessObjectC.h"
@implementation BusinessObjectC
-(void)handleBusiness:(CompletionBlock)completion{
NSLog(@"BusinessObjectC");
if ([self.LB.text isEqualToString:@"0"]) {
completion(YES);
}else{
completion(NO);
}
}
@end
//模拟处理逻辑优先级
#import "ViewController.h"
#import "BusinessObjectA.h"
#import "BusinessObjectB.h"
#import "BusinessObjectC.h"
@interface ViewController ()
//背景变红色
@property (nonatomic,assign) BOOL isOuShu;
@property (weak, nonatomic) IBOutlet UILabel *LBOne;
@property (weak, nonatomic) IBOutlet UILabel *LBTwo;
@property (weak, nonatomic) IBOutlet UILabel *LBThree;
@property (nonatomic,strong) NSArray *testArray;
@property (weak, nonatomic) IBOutlet UIButton *testBtn;
@end
@implementation ViewController
-(NSArray *)testArray{
if(!_testArray){
_testArray = @[@1,@2,@3];
}
return _testArray;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.}
- (IBAction)ClickAction:(id)sender {
int x = arc4random() % 3;//0 1 2 模拟责任链中密码、手势、指纹的优先级
self.LBOne.text = [NSString stringWithFormat:@"%d",x];
self.LBTwo.text = [NSString stringWithFormat:@"%d",x-1];
self.LBThree.text = [NSString stringWithFormat:@"%d",x-2];
//开始责任链
//a指纹
BusinessObjectA *objA = [BusinessObjectA new];
objA.LB = self.LBOne;
[objA handle:^(BusinessObject * _Nonnull handler, BOOL handled) {
if(handled){
NSLog(@"a_yes_handler_test:%@",handler.LB.text);
[self.testBtn setTitle:@"LBOne" forState:UIControlStateNormal];
}else{
NSLog(@"a_no_handler_test:%@",handler.LB.text);
}
}];
//b手势
BusinessObjectB *objB = [BusinessObjectB new];
objB.LB = self.LBTwo;
objA.nextBusiness = objB;
[objB handle:^(BusinessObject * _Nonnull handler, BOOL handled) {
if(handled){
NSLog(@"b_yes_handler_test:%@",handler.LB.text);
[self.testBtn setTitle:@"LBTwo" forState:UIControlStateNormal];
}else{
NSLog(@"b_no_handler_test:%@",handler.LB.text);
}
}];
//cOCR
BusinessObjectC *objC = [BusinessObjectC new];
objC.LB = self.LBThree;
objB.nextBusiness = objC;
[objC handle:^(BusinessObject * _Nonnull handler, BOOL handled) {
if(handled){
[self.testBtn setTitle:@"LBThree" forState:UIControlStateNormal];
NSLog(@"c_yes_handler_test:%@",handler.LB.text);
}else{
NSLog(@"c_no_handler_test:%@",handler.LB.text);
}
}];
}
@end
相关文章:
责任链vs金融登录
金融app相对普通app而言,出于安全考虑,其安全校验方式比较多,以某些银行app为例,手机号登录成功后,会增加指纹、手势、OCR人脸等验证!这些安全项的校验,会根据用户的风险等级有不同的校验优先级…...
通过VIOOVI,了解联合作业分析的意义和目标!
现如今企业的主流生产模式就是流水线生产,一道工序结束后,紧接着开展下一项工序,这种作业模式可以以一种比较高效的方式缩减生产时间。尽管流水作业的效率已经够高的了,但是各个工序之间如果衔接不到位的话,会造成生产…...
清洁机器人规划控制方案
清洁机器人规划控制方案 作者联系方式Forrest709335543qq.com 文章目录 清洁机器人规划控制方案方案简介方案设计模块链路坐标变换算法框架 功能设计定点自主导航固定路线清洁区域覆盖清洁贴边沿墙清洁自主返航回充 仿真测试仿真测试准备定点自主导航测试固定路线清洁测试区域…...
设计模式 - 工厂模式
一、 简单工厂(Simple Factory Pattern) 1、概念 一个工厂对象决定创建出哪一种产品类的实力,但不属于GOF23种设计模式。 简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创…...
elementUI this.$confirm 文字大小样式
dangerouslyUseHTMLString:true // message部分 以html片段处理 customClass //MessageBox 的自定义类名 整个comfirm框自定义类名 cancelButtonClass // 取消按钮的自定义类名 confirmButtonClass // 确定按钮的自定义类名<style> .addcomfirm{width: 500px; } .a…...
Kafka的TimingWheel
Kafka的TimingWheel是Kafka中的一个时间轮实现,用于管理和处理延迟消息。时间轮是一种定时器的数据结构,可以高效地管理和触发定时事件。 在Kafka中,TimingWheel用于处理延迟消息的重试。当Kafka生产者发送消息到Kafka集群,但由于某些原因导致消息发送失败,生产者会将这些…...
第2集丨webpack 江湖 —— 创建一个简单的webpack工程demo
目录 一、创建webpack工程1.1 新建 webpack工程目录1.2 项目初始化1.3 新建src目录和文件1.4 安装jQuery1.5 安装webpack1.6 配置webpack1.6.1 创建配置文件:webpack.config.js1.6.2 配置dev脚本1.7 运行dev脚本 1.8 查看效果1.9 附件1.9.1 package.json1.9.2 webpa…...
Python(Web时代)——初识flask
flask简介 介绍 Flask是一个用Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务。它是BSD授权的,一个有少量限制的免费软件许可。它使用了 Werkzeug 工具箱和 Jinja2 模板引擎。 Flask 的设计理念是简单、灵活、易于扩展&a…...
二、SQL-5.DQL-8).案例练习
1、查询年龄为20,21,22,23岁的员工信息 select * from emp where age in(20, 21, 22, 23) and gender 女; 2、查询性别为男,并且年龄在20-40岁(含)以内的姓名为三个字的员工 select * from emp where gender 男 && age between 2…...
浙大数据结构第五周之05-树7 堆中的路径
题目详情: 将一系列给定数字依次插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。 输入格式: 每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-1…...
C# Modbus TCP上位机测试
前面说了三菱和西门子PLC的上位机通信,实际在生产应用中,设备会有很多不同的厂家生产的PLC,那么,我们就需要一种通用的语言,进行设备之间的通信,工业上较为广泛使用的语言之一就是Modbus。 Modbus有多种连…...
instr字符查找函数(oracle用instr来代替like)
instr函数:字符查找函数。其功能是查找一个字符串在另一个字符串中首次出现的位置。 instr函数在Oracle/PLSQL中是返回要截取的字符串在源字符串中的位置。 语法 instr( string1, string2, start_position,nth_appearance ) 参数 string1:源字符串&am…...
trie树的一点理解
这个是最简单的数据结构:因为只需要记住两句话就能完美的写出简洁优雅的代码 1. 每次都是从根节点开始看(或者说从第零次插入的东西开始遍历,son[][]里面存的是第几次插入) 2每次遍历都是插入和查询的字符串 #include<iostream> using namespace …...
Linux CentOS监控系统的运行情况工具 - top/htop/glances/sar/nmon
在CentOS系统中,您可以使用以下工具来监控系统的运行情况: 1. top: top 是一个命令行工具,用于实时监控系统的进程、CPU、内存和负载情况。您可以使用以下命令来启动 top: top 输出 2. htop: htop 是一…...
Qt开发(2)——windows下调用外部程序
一、QProcess::start 1.阻塞性 start是非阻塞函数,但是这里的waitForFinished是阻塞的 2. 调用外部压缩程序7z // 目标压缩路径 QString zipFilePath destinationFolder "/" zipFileName; QStringList arguments{"a&qu…...
PostgreSQL查看数据库对象大小
PostgreSQL查看数据库对象大小 PostgreSQL查看数据库对象大小1、查看某个数据库大小2、查看多个数据库大小3、按顺序查看索引大小4、查看所有对象的大小 PostgreSQL查看数据库对象大小 1、查看某个数据库大小 select pg_size_pretty(pg_database_size(tzqdb));2、查看多个数据…...
给el-table实现列显隐
用过若依的都知道,在使用el-table 时候,实现列显隐效果是要给每个列加v-if 判断的,这种代码过于繁琐,于是翻看el-table包的代码,调试后发现内部的【插入】和【删除】两个方法可以达到我们要的效果。 项目不提供源码&a…...
为Android构建现代应用——应用架构
选择风格(Choosing a style) 我们将依照Google在《应用架构指南》中推荐的最佳实践和架构指南来构建OrderNow的架构。 这些定义包括通过各层定义组件的一些Clean Architecture原则。 层次的定义(Definition of the layers) 在应用程序中,我们将定义以下主要层次…...
49:字符串的新增方法
字符串的新增方法 String.fromCodePoint()String.raw()实例方法:codePointAt()实例方法:normalize()[实例方法:includes(), startsWith(), endsWith()](https://es6.ruanyifeng.com/#docs/string-methods#实例方法:includes(), s…...
Kaggle图表内容识别大赛TOP方案汇总
赛题名称:Benetech - Making Graphs Accessible 赛题链接:https://www.kaggle.com/competitions/benetech-making-graphs-accessible 赛题背景 数以百万计的学生有学习、身体或视力障碍,导致人们无法阅读传统印刷品。这些学生无法访问科学…...
3种方案玩转赛博朋克2077存档修改:从入门到精通的技术指南
3种方案玩转赛博朋克2077存档修改:从入门到精通的技术指南 【免费下载链接】CyberpunkSaveEditor A tool to edit Cyberpunk 2077 sav.dat files 项目地址: https://gitcode.com/gh_mirrors/cy/CyberpunkSaveEditor 赛博朋克2077存档编辑器是一款专业级游戏数…...
人流后多久干净才算正常?行业洞察与科学修护指南
人工流产后,出血排净时间是判断身体恢复状态的核心指标,也是女性关注的首要问题。结合行业研究与临床实践,本文将深入解析人流后出血的正常范围、异常信号,同时结合行业修护标准,为女性提供科学、实用的恢复指引&#…...
从一次现场故障说起:如何通过分析三相变压器感应电动势的谐波来预判铁芯隐患?
三相变压器谐波诊断实战:从波形异常到铁芯隐患精准预判 去年夏天,某220kV变电站的主变在例行巡检中被发现输出电压波形出现明显畸变——这本是电力运维中常见的"小异常",但当我们深入分析谐波成分后,却揭露出一个潜在的…...
个人信息保护:使用AI工具必须知道的隐私安全指南
个人信息保护的重要性AI工具的普及带来了便利,但也存在隐私泄露风险。未经保护的个人信息可能被滥用,导致身份盗窃、诈骗等问题。了解隐私安全措施至关重要。选择可信的AI工具优先选择有明确隐私政策、数据加密措施的工具。查看工具是否通过第三方安全认…...
5分钟搞定!Universal Pokemon Randomizer ZX:让宝可梦游戏焕发新生
5分钟搞定!Universal Pokemon Randomizer ZX:让宝可梦游戏焕发新生 【免费下载链接】universal-pokemon-randomizer-zx Public repository of source code for the Universal Pokemon Randomizer ZX 项目地址: https://gitcode.com/gh_mirrors/un/univ…...
seo 优化计划包括哪些内容
SEO优化计划:打造高效网站流量的全面指南 在当前数字化时代,一个成功的网站离不开高效的搜索引擎优化(SEO)策略。SEO优化计划是一项复杂而多层次的工作,其目的是提升网站在搜索引擎结果中的排名,从而吸引更…...
python tarfile
# Python tarfile模块:不止是打包与解包 在Python的标准库中,tarfile模块常常被开发者们忽视,或者仅仅被当作一个简单的压缩工具来使用。实际上,这个模块的功能远比表面看起来要丰富得多,它处理的是tar格式的归档文件…...
如何用QtScrcpy突破手机操控局限?三大创新方案让多场景效率提升300%
如何用QtScrcpy突破手机操控局限?三大创新方案让多场景效率提升300% 【免费下载链接】QtScrcpy Android real-time display control software 项目地址: https://gitcode.com/GitHub_Trending/qt/QtScrcpy 手机屏幕太小导致操作失误?多设备管理切…...
2025届学术党必备的六大AI科研网站推荐榜单
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 为能切实有效地把文本的AIGC检测概率给降低下来,得从业经历连贯性以及统计规律这…...
OpenCore Legacy Patcher技术解析:老旧Mac设备的macOS现代化方案
OpenCore Legacy Patcher技术解析:老旧Mac设备的macOS现代化方案 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 一、工具概述与价值定位 OpenCo…...
