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

责任链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而言&#xff0c;出于安全考虑&#xff0c;其安全校验方式比较多&#xff0c;以某些银行app为例&#xff0c;手机号登录成功后&#xff0c;会增加指纹、手势、OCR人脸等验证&#xff01;这些安全项的校验&#xff0c;会根据用户的风险等级有不同的校验优先级…...

通过VIOOVI,了解联合作业分析的意义和目标!

现如今企业的主流生产模式就是流水线生产&#xff0c;一道工序结束后&#xff0c;紧接着开展下一项工序&#xff0c;这种作业模式可以以一种比较高效的方式缩减生产时间。尽管流水作业的效率已经够高的了&#xff0c;但是各个工序之间如果衔接不到位的话&#xff0c;会造成生产…...

清洁机器人规划控制方案

清洁机器人规划控制方案 作者联系方式Forrest709335543qq.com 文章目录 清洁机器人规划控制方案方案简介方案设计模块链路坐标变换算法框架 功能设计定点自主导航固定路线清洁区域覆盖清洁贴边沿墙清洁自主返航回充 仿真测试仿真测试准备定点自主导航测试固定路线清洁测试区域…...

设计模式 - 工厂模式

一、 简单工厂&#xff08;Simple Factory Pattern&#xff09; 1、概念 一个工厂对象决定创建出哪一种产品类的实力&#xff0c;但不属于GOF23种设计模式。 简单工厂适用于工厂类负责创建的对象较少的场景&#xff0c;且客户端只需要传入工厂类的参数&#xff0c;对于如何创…...

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 创建配置文件&#xff1a;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 微框架&#xff0c;让我们可以使用Python语言快速实现一个网站或Web服务。它是BSD授权的&#xff0c;一个有少量限制的免费软件许可。它使用了 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、查询性别为男&#xff0c;并且年龄在20-40岁&#xff08;含&#xff09;以内的姓名为三个字的员工 select * from emp where gender 男 && age between 2…...

浙大数据结构第五周之05-树7 堆中的路径

题目详情&#xff1a; 将一系列给定数字依次插入一个初始为空的小顶堆H[]。随后对任意给定的下标i&#xff0c;打印从H[i]到根结点的路径。 输入格式: 每组测试第1行包含2个正整数N和M(≤1000)&#xff0c;分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-1…...

C# Modbus TCP上位机测试

前面说了三菱和西门子PLC的上位机通信&#xff0c;实际在生产应用中&#xff0c;设备会有很多不同的厂家生产的PLC&#xff0c;那么&#xff0c;我们就需要一种通用的语言&#xff0c;进行设备之间的通信&#xff0c;工业上较为广泛使用的语言之一就是Modbus。 Modbus有多种连…...

instr字符查找函数(oracle用instr来代替like)

instr函数&#xff1a;字符查找函数。其功能是查找一个字符串在另一个字符串中首次出现的位置。 instr函数在Oracle/PLSQL中是返回要截取的字符串在源字符串中的位置。 语法 instr( string1, string2, start_position,nth_appearance ) 参数 string1&#xff1a;源字符串&am…...

trie树的一点理解

这个是最简单的数据结构&#xff1a;因为只需要记住两句话就能完美的写出简洁优雅的代码 1. 每次都是从根节点开始看(或者说从第零次插入的东西开始遍历&#xff0c;son[][]里面存的是第几次插入) 2每次遍历都是插入和查询的字符串 #include<iostream> using namespace …...

Linux CentOS监控系统的运行情况工具 - top/htop/glances/sar/nmon

在CentOS系统中&#xff0c;您可以使用以下工具来监控系统的运行情况&#xff1a; 1. top&#xff1a; top 是一个命令行工具&#xff0c;用于实时监控系统的进程、CPU、内存和负载情况。您可以使用以下命令来启动 top&#xff1a; top 输出 2. htop&#xff1a; htop 是一…...

Qt开发(2)——windows下调用外部程序

一、QProcess::start &#xff11;&#xff0e;阻塞性 start是非阻塞函数&#xff0c;但是这里的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实现列显隐

用过若依的都知道&#xff0c;在使用el-table 时候&#xff0c;实现列显隐效果是要给每个列加v-if 判断的&#xff0c;这种代码过于繁琐&#xff0c;于是翻看el-table包的代码&#xff0c;调试后发现内部的【插入】和【删除】两个方法可以达到我们要的效果。 项目不提供源码&a…...

为Android构建现代应用——应用架构

选择风格(Choosing a style) 我们将依照Google在《应用架构指南》中推荐的最佳实践和架构指南来构建OrderNow的架构。 这些定义包括通过各层定义组件的一些Clean Architecture原则。 层次的定义(Definition of the layers) 在应用程序中&#xff0c;我们将定义以下主要层次…...

49:字符串的新增方法

字符串的新增方法 String.fromCodePoint()String.raw()实例方法&#xff1a;codePointAt()实例方法&#xff1a;normalize()[实例方法&#xff1a;includes(), startsWith(), endsWith()](https://es6.ruanyifeng.com/#docs/string-methods#实例方法&#xff1a;includes(), s…...

Kaggle图表内容识别大赛TOP方案汇总

赛题名称&#xff1a;Benetech - Making Graphs Accessible 赛题链接&#xff1a;https://www.kaggle.com/competitions/benetech-making-graphs-accessible 赛题背景 数以百万计的学生有学习、身体或视力障碍&#xff0c;导致人们无法阅读传统印刷品。这些学生无法访问科学…...

[具身智能-229]:OpenCV 的 DNN (Deep Neural Networks) 模块,可以直接加载和运行,通过PyTorch AI框架训练好的模型,而不需要安装PyTorch AI框架

OpenCV 的 DNN (Deep Neural Networks) 模块确实是工业界和边缘计算领域非常推崇的推理引擎。它的核心定位不是“训练模型”&#xff0c;而是“让训练好的模型跑得更快、更轻、更通用”。它允许开发者在不依赖庞大的 TensorFlow 或 PyTorch 库的情况下&#xff0c;直接在生产环…...

SECS协议实战:从报警触发到Trace数据采集的完整指南

1. SECS协议基础与报警管理实战 半导体设备通信领域有个"隐形语言"叫SECS/GEM协议&#xff0c;它就像设备间的摩斯密码。今天咱们重点聊聊其中两个高频功能&#xff1a;报警管理&#xff08;S5F1&#xff09;和Trace数据采集&#xff08;S2F23/S6F1&#xff09;。先看…...

瑞芯微RK3588硬件设计资料概览

瑞芯微RK3588硬件设计资料 瑞芯微RK3588硬件设计资料资料包括&#xff1a;原理图和PCB以及叠层设计说明&#xff0c;硬件设计指导书等原理图和pcb用cadence打开该原理图和pcb基于网络硬盘录像机项目设计可作为RK3588学习者作为参考电路使用&#xff0c;或者学习高速电路者学习使…...

FNF-PsychEngine完全指南:从零开始打造你的音乐游戏

FNF-PsychEngine完全指南&#xff1a;从零开始打造你的音乐游戏 【免费下载链接】FNF-PsychEngine Engine originally used on Mind Games mod 项目地址: https://gitcode.com/gh_mirrors/fn/FNF-PsychEngine FNF-PsychEngine是一款功能强大的Friday Night Funkin开源游…...

如何5分钟搞定全网音乐歌词:163MusicLyrics终极使用指南

如何5分钟搞定全网音乐歌词&#xff1a;163MusicLyrics终极使用指南 【免费下载链接】163MusicLyrics 云音乐歌词获取处理工具【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 163MusicLyrics是一款专业的开源音乐歌词获取工具&am…...

scrcpy如何实现35ms超低延迟的Android屏幕镜像体验?

scrcpy如何实现35ms超低延迟的Android屏幕镜像体验&#xff1f; 【免费下载链接】scrcpy Display and control your Android device 项目地址: https://gitcode.com/gh_mirrors/sc/scrcpy scrcpy是一款开源的Android设备屏幕镜像与控制工具&#xff0c;能够在电脑上实时…...

Edge浏览器+豆包插件:5分钟搞定Arxiv论文翻译与AI问答(保姆级教程)

Edge浏览器豆包插件&#xff1a;科研新手的Arxiv论文高效阅读指南 第一次打开Arxiv上那篇关键论文时&#xff0c;我盯着满屏的专业术语和复杂句式发呆了半小时——作为非英语母语的研究者&#xff0c;这场景太熟悉了。直到发现Edge浏览器上的豆包插件&#xff0c;才真正打开了…...

无人机飞控编程实战:从欧拉角到机体角速度,用Python/Matlab搞定姿态解算

无人机飞控编程实战&#xff1a;从欧拉角到机体角速度的姿态解算 当你在调试无人机时&#xff0c;发现姿态数据出现异常波动&#xff1b;当机器人在快速转向时&#xff0c;控制系统突然变得不稳定——这些问题的根源往往在于姿态解算的精度和实时性。作为飞控开发者&#xff0c…...

5分钟快速上手:BiliTools哔哩哔哩工具箱2026年终极跨平台解决方案

5分钟快速上手&#xff1a;BiliTools哔哩哔哩工具箱2026年终极跨平台解决方案 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱&#xff0c;支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliT…...

跨平台文件传输与多设备协同办公的高效解决方案:AirDropPlus技术测评

跨平台文件传输与多设备协同办公的高效解决方案&#xff1a;AirDropPlus技术测评 【免费下载链接】AirDropPlus A file transfer and clipboard synchronization tool between Windows and iOS devices implemented by Python and Shortcuts. 项目地址: https://gitcode.com/…...