当前位置: 首页 > 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;导致人们无法阅读传统印刷品。这些学生无法访问科学…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...