「责任链 Chain Of Responsibility 」 Swift实现

news/2024/5/19 14:24:44 标签: 设计模式, 责任链模式, swift, ios

责任链模式

  • 概念
  • 示例: 业务场景 一
  • 示例: 业务场景 二

概念

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,用于将请求连续传递给多个处理器直到被处理为止。在 Swift 中,可以使用类来实现责任链模式

示例: 业务场景 一

我们可以实现一个处理销售订单的责任链,有以下三种处理器:

  • 销售经理(SalesManager):处理订单金额范围在0到1000之间的订单。
  • 财务部门(FinanceDepartment):处理订单金额范围在1000到5000之间的订单。
  • 总经理(GeneralManager):处理订单金额超过5000的订单。

下面是 Swift 中责任链模式实现

swift">
protocol OrderHandler {
    var next: OrderHandler? {get set}
    func handleOrder(amount: Double)
}

class SalesManager: OrderHandler {
    var next: OrderHandler?
    func handleOrder(amount: Double) {
        if amount < 100 {
            print("小职员 可以已经处理 价值 \(amount) 的货物")
        } else {
            next?.handleOrder(amount: amount)
        }
    }
}

class FinanceDepartment: OrderHandler {
    var next: OrderHandler?
    func handleOrder(amount: Double) {
        if amount < 1000 {
            print("财务总监 可以已经处理 价值 \(amount) 的货物")
        } else {
            next?.handleOrder(amount: amount)
        }
    }
}

class GeneralManager: OrderHandler {
    var next: OrderHandler?
    func handleOrder(amount: Double) {
        if amount < 10000 {
            print("总经理 可以已经处理 价值 \(amount) 的货物")
        } else {
            print("没有人能处理这个 货物")
        }
    }
}

调用方式

swift"> 		let salesManager = SalesManager()
        let financeDepartment = FinanceDepartment()
        let generalManager = GeneralManager()
        
        salesManager.next = financeDepartment
        financeDepartment.next = generalManager
        generalManager.next = nil
        
        financeDepartment.handleOrder(amount: 100.0)
        financeDepartment.handleOrder(amount: 20000.0)

在上面的代码中,我们定义了一个 OrderHandler 协议,该协议包含一个 handleOrder(amount:) 方法和一个可选属性 next,用于构建责任链。对于每个订单,可以逐一调用责任链上的每个处理器,直到订单得到处理为止。

客户端操作如下:

  1. 创建销售经理(SalesManager)、财务部门(FinanceDepartment)和总经理(GeneralManager)对象,并设置下一个处理器。
  2. 调用销售经理处理订单的方法。
  3. 根据订单金额,逐一调用责任链上的处理器,直到找到能够处理该订单的处理器为止。

示例: 业务场景 二

以处理用户登录的示例为例
我们将创建一个基于责任链模式的用户登录过程,其涉及以下步骤:

  • 判断用户名是否存在。
  • 判断用户密码是否正确。
  • 是否启用了双重验证或两步验证。
  • 是否已通过所有安全检查,允许用户登录。

如果某个步骤未成功完成,则不会执行后续步骤。

实现如下

swift">
// 处理用户请求的责任链
protocol LoginHandler {
    var next: LoginHandler? { get set }
    func handle(request: LoginRequest)
}

// 用户登录请求
struct LoginRequest {
    let username: String
    let password: String
    var isTwoFactorAuthEnabled: Bool = false
    var isSecurityCheckPassed: Bool = false
}

// 判断用户名是否存在的处理器
class CheckUsernameHandler: LoginHandler {
    var next: LoginHandler?
    
    func handle(request: LoginRequest) {
        if request.username.count == 0 {
            print("用户名不能为空")
        } else {
            next?.handle(request: request)
        }
    }
}

// 判断用户密码是否正确的处理器
class CheckPasswordHandler: LoginHandler {
    var next: LoginHandler?
    
    func handle(request: LoginRequest) {
        if request.password.count == 0 {
            print("密码不能为空")
        } else {
            next?.handle(request: request)
        }
    }
}

// 双重验证或两步验证处理器
class TwoFactorAuthHandler: LoginHandler {
    var next: LoginHandler?
    
    func handle(request: LoginRequest) {
        if request.isTwoFactorAuthEnabled {
            print("请通过双重验证或两步验证")
        } else {
            next?.handle(request: request)
        }
    }
}

// 安全检测处理器
class SecurityCheckHandler: LoginHandler {
    var next: LoginHandler?
    
    func handle(request: LoginRequest) {
        if request.isSecurityCheckPassed {
            print("登录成功")
        } else {
            print("安全检测未通过,请联系管理员")
        }
    }
}

调用方式

swift">let checkUsernameHandler = CheckUsernameHandler()
let checkPasswordHandler = CheckPasswordHandler()
let twoFactorAuthHandler = TwoFactorAuthHandler()
let securityCheckHandler = SecurityCheckHandler()

checkUsernameHandler.next = checkPasswordHandler
checkPasswordHandler.next = twoFactorAuthHandler
twoFactorAuthHandler.next = securityCheckHandler

let request1 = LoginRequest(username: "test", password: "", isTwoFactorAuthEnabled: false, isSecurityCheckPassed: false)
checkUsernameHandler.handle(request: request1)

let request2 = LoginRequest(username: "test", password: "test123", isTwoFactorAuthEnabled: true, isSecurityCheckPassed: false)
checkUsernameHandler.handle(request: request2)

let request3 = LoginRequest(username: "test", password: "test123", isTwoFactorAuthEnabled: false, isSecurityCheckPassed: true)
checkUsernameHandler.handle(request: request3)

在上述代码中,我们首先定义了 LoginHandler 责任链模式,然后连续添加了四个处理器,用于检查用户名、密码、双重验证或两步验证,以及安全检查。如果给定的登录请求未通过任何一项,则停止责任链。

客户端调用的示例代码如下所示:

  1. 创建 LoginRequest 对象,并在创建 CheckUsernameHandler 处理器后调用 handle(request:) 方法,开始责任链流程。
  2. 逐一调用责任链上的每个处理器,直到找到能够处理该请求的处理器为止。
  3. 如果未通过任何一项,则停止责任链。

输出结果如下:

密码不能为空
请通过双重验证或两步验证
登录成功

这个例子简单演示了如何在 Swift 中使用责任链模式处理流程。


http://www.niftyadmin.cn/n/352550.html

相关文章

Linux/Ubuntu系统运行Python+Yolov5物体识别

程序示例精选 Linux/Ubuntu系统运行PythonYolov5物体识别 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<Linux/Ubuntu系统运行PythonYolov5物体识别>>编写代码&#xff0c;代码…

自然语言处理技术简介

长期以来&#xff0c;研究人员进行自然语言处理研究主要依赖各种机器学习模型&#xff0c;以及手工设计的特征&#xff0c;但这样做带来的隐患是由于语言信息被稀疏表征表示&#xff0c;会出现维度诅咒之类的问题。而随着近年来词嵌入&#xff08;低维、分布式表征&#xff09;…

Redis事务和Redis管道

什么是Redis事务:Redis事务是指将多条命令加入到队列里面&#xff0c;一次批量执行多条命令&#xff0c;每一条命令会按顺序执行&#xff0c;在事务执行过程中不会受到客户端所传入的命令请求的影响 1)单独的隔离操作:Redis的事务仅仅保证事务 里面的操作会被连续独占的执行&am…

2023年最新苹果账号更改/注册为美区账号及免国外支付购买和充值美区App Store礼品卡教程

平时大家在使用IPhone手机时,应该有遇到软件明明是在App Store里上架的,但自己无论如何也搜索不到的情况吧!这种就是因为应用没有上架到你苹果账号所在的国家地区才导致的搜不到无法下载。比如:部分的新闻类、代[过滤]理类、游戏类应用以及Chat GPT等都无法在国区账号中搜索…

MATLAB入门教程005||MATLAB运算符||MATLAB算术运算

MATLAB运算符 MATLAB运算符 数组中唯一的值运算符是一个符号&#xff0c;它将要执行的数学或者逻辑操作传达给编译器执行。 MATLAB 设计工作主要是对整个矩阵和阵列。因此&#xff0c;运算符在 MATLAB 工作标和非标量数据。 MATLAB 的基本运算类型&#xff1a; 算术运算符…

包管理工具详解npm、yarn、cnpm、npx、pnpm

目录&#xff1a; 1 npm包管理工具 2 package配置文件 3 npm install原理 4 yarn、cnpm、npx 5 发布自己的开发包 6 pnpm使用和原理 当我们使用npm install xxxx 的时候会添加一个node_module和2个json文件&#xff1a; package.json是配置信息文件&#xff0c;  这个配…

Guitar Pro8吉他软件主要功能详解及安装教程

Guitar Pro是一款专业的吉他软件&#xff0c;它支持所有的4至8弦的弹拔乐器&#xff08;吉他&#xff0c;贝司&#xff0c;班卓琴&#xff0c;曼陀铃等等&#xff0c;所以不论是初学者还是高手&#xff0c;都希望利用他来创作音乐&#xff0c;或者是用来充当一个虚拟的乐队。 …

linux下cpu占用率100%怎么解决?

在实际的生产环境中&#xff0c;常常会遇到服务器CPU爆满的问题&#xff0c;这时候&#xff0c;正确的排查方法&#xff0c;有助于快速的定位问题。 1、找到最耗CPU的进程 使用top命令查看系统总体的CPU和内存使用情况&#xff0c;以及各个进程的资源使用情况。 2、找到最耗…