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

Protocol函数独立实现:ViewController代码瘦身可行性问询

Absolutely! Creating a dedicated Service class to handle your protocol conformance is a fantastic way to cut down on ViewController bloat—here’s a step-by-step breakdown of how to make it work, plus some extra tricks to keep your code even cleaner:

1. Shift Protocol Conformance to a Service Class

Instead of making your ViewController implement every method in the 10-function protocol, offload that work to a separate Service class. This class will handle the business logic tied to the protocol methods, while your ViewController only deals with UI-specific updates.

Example Implementation:

First, your original protocol (we’ll use Swift for this example):

protocol DataPassingProtocol: AnyObject {
    func didUpdateUser(_ user: User)
    func didCompleteTask(_ task: Task)
    // ... 8 additional protocol methods
}

Now create the Service class that conforms to the protocol:

class DataPassingService: DataPassingProtocol {
    // Keep a weak reference to your ViewController to avoid retain cycles
    weak var parentVC: ViewController?
    
    // MARK: - DataPassingProtocol Methods
    func didUpdateUser(_ user: User) {
        // Handle business logic here (e.g., update local cache, sync with backend)
        UserCache.shared.saveUser(user)
        // Notify the ViewController to update UI if needed
        parentVC?.refreshUserDisplay(with: user)
    }
    
    func didCompleteTask(_ task: Task) {
        // Process task completion logic
        TaskManager.shared.markTaskAsComplete(task)
        parentVC?.showTaskSuccessAlert()
    }
    
    // For protocol methods that don't require UI updates, add default/empty implementations
    func unusedProtocolMethod() {
        // No-op, or handle generic logic here
    }
    
    // Repeat for all remaining protocol methods
}

Then in your ViewController, use the Service as the delegate:

class ViewController: UIViewController {
    private let dataService = DataPassingService()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        dataService.parentVC = self
        
        // Pass the service as the delegate to other ViewControllers/components
        let detailVC = DetailViewController()
        detailVC.delegate = dataService
    }
    
    // Only implement methods that directly relate to UI updates
    func refreshUserDisplay(with user: User) {
        userNameLabel.text = user.fullName
        userAvatarImageView.image = user.avatar
    }
    
    func showTaskSuccessAlert() {
        let alert = UIAlertController(title: "Success!", message: "Task completed", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
}
2. Extra Strategies to Refine Your Setup

To make this even more scalable, consider these complementary approaches:

  • Split Your Large Protocol into Smaller Ones
    Instead of one monolithic protocol, break it into focused, single-responsibility protocols. For example:

    protocol UserUpdateDelegate: AnyObject {
        func didUpdateUser(_ user: User)
    }
    
    protocol TaskCompletionDelegate: AnyObject {
        func didCompleteTask(_ task: Task)
    }
    
    // Optional: Keep the original protocol for backward compatibility
    protocol DataPassingProtocol: UserUpdateDelegate, TaskCompletionDelegate {
        // Remaining methods...
    }
    

    This way, ViewControllers or Services only need to conform to the protocols they actually use, reducing unnecessary code.

  • Use Optional Protocol Methods (If Compatible with Objective-C)
    If your codebase can work with Objective-C interoperability, you can mark protocol methods as optional:

    @objc protocol DataPassingProtocol {
        @objc optional func didUpdateUser(_ user: User)
        @objc optional func didCompleteTask(_ task: Task)
        // ...
    }
    

    Note that you’ll need to check if a delegate responds to a method before calling it (e.g., delegate?.didUpdateUser?(user)), which can add minor boilerplate. For pure Swift codebases, splitting protocols is usually a cleaner choice.

3. Why This Approach Works
  • Separation of Concerns: Your ViewController stays focused on UI logic, while the Service handles business rules and protocol compliance.
  • Reusability: The Service can be shared across multiple ViewControllers, eliminating duplicate protocol implementations.
  • Maintainability: Changes to protocol logic only need to be made in one place (the Service), instead of updating every ViewController that conforms.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:13:11