You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ViewController中的输入验证函数迁移至MVP架构?

基于MVP架构拆分密码验证UI逻辑的实现方案

核心思路

把原ViewController里的验证逻辑和UI更新触发逻辑剥离到Presenter层,让ViewController只负责接收用户输入、响应Presenter的指令更新UI,贴合MVP架构中「View只管展示、Presenter处理业务逻辑」的分工原则。

具体实现步骤

1. 定义View协议(MVP中View的抽象约定)

先定义一个协议,明确View需要实现的UI更新方法,让ViewController遵守该协议:

protocol PasswordValidationView: AnyObject {
    /// 更新长度验证标记的显示状态
    func updateLengthCheckmark(hidden: Bool)
    /// 更新大写字母验证标记的显示状态
    func updateUppercaseCheckmark(hidden: Bool)
    /// 更新数字验证标记的显示状态
    func updateNumberCheckmark(hidden: Bool)
    /// 更新特殊字符验证标记的显示状态
    func updateSymbolCheckmark(hidden: Bool)
    /// 更新重置按钮的显示状态
    func updateResetButton(hidden: Bool)
}

2. 创建Presenter类(封装业务逻辑)

Presenter持有View的弱引用,把原ViewController里的验证逻辑迁移过来,计算完状态后通过协议通知View更新UI:

class PasswordValidationPresenter {
    weak var view: PasswordValidationView?
    
    func validatePassword(_ text: String?) {
        guard let password = text else {
            // 空输入时隐藏所有验证标记和按钮
            view?.updateLengthCheckmark(hidden: true)
            view?.updateUppercaseCheckmark(hidden: true)
            view?.updateNumberCheckmark(hidden: true)
            view?.updateSymbolCheckmark(hidden: true)
            view?.updateResetButton(hidden: true)
            return
        }
        
        let hasMinimumLength = TextValidationHelper.validateHasMinimumLength(password: password)
        let hasCapitalLetter = TextValidationHelper.validateHasCapitalLetter(password: password)
        let hasNumber = TextValidationHelper.validateHasNumber(password: password)
        let hasSpecialCharacter = TextValidationHelper.validateHasSpecialCharacter(password: password)
        
        // 通知View更新各个UI组件状态
        view?.updateLengthCheckmark(hidden: !hasMinimumLength)
        view?.updateUppercaseCheckmark(hidden: !hasCapitalLetter)
        view?.updateNumberCheckmark(hidden: !hasNumber)
        view?.updateSymbolCheckmark(hidden: !hasSpecialCharacter)
        
        let allConditionsMet = hasMinimumLength && hasCapitalLetter && hasNumber && hasSpecialCharacter
        view?.updateResetButton(hidden: !allConditionsMet)
    }
}

3. 修改ViewController(作为MVP的View层)

ViewController实现PasswordValidationView协议,初始化Presenter并绑定关联,把原IBAction的逻辑简化为传递输入给Presenter:

class YourViewController: UIViewController, PasswordValidationView {
    // 原有的UI组件声明
    @IBOutlet weak var passLengthCheckmarkImageView: UIImageView!
    @IBOutlet weak var passHasUppercaseCheckmarkImageView: UIImageView!
    @IBOutlet weak var passHasNumberCheckmarkImageView: UIImageView!
    @IBOutlet weak var passHasSymbolCheckmarkImageView: UIImageView!
    @IBOutlet weak var resetButton: UIButton!
    
    // 初始化Presenter
    let validationPresenter = PasswordValidationPresenter()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 绑定Presenter与View的关联
        validationPresenter.view = self
    }
    
    // 原输入响应方法,现在仅负责传递输入内容给Presenter
    @IBAction func onEmailValueChanged(_ sender: UITextField) {
        validationPresenter.validatePassword(sender.text)
    }
    
    // 实现PasswordValidationView协议的UI更新方法
    func updateLengthCheckmark(hidden: Bool) {
        passLengthCheckmarkImageView.isHidden = hidden
    }
    
    func updateUppercaseCheckmark(hidden: Bool) {
        passHasUppercaseCheckmarkImageView.isHidden = hidden
    }
    
    func updateNumberCheckmark(hidden: Bool) {
        passHasNumberCheckmarkImageView.isHidden = hidden
    }
    
    func updateSymbolCheckmark(hidden: Bool) {
        passHasSymbolCheckmarkImageView.isHidden = hidden
    }
    
    func updateResetButton(hidden: Bool) {
        resetButton.isHidden = hidden
    }
}

是否需要更多代码?

你当前提供的代码已经足够完成MVP架构的拆分。如果TextValidationHelper有特殊依赖、或者ViewController还有其他关联业务逻辑(比如密码提交、额外错误提示),补充相关代码可以让方案更贴合你的实际场景,但现有信息已经能给出完整的核心拆分方案。

内容的提问来源于stack exchange,提问作者fabiobh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 06:10:32