Swift-协议写扩展的妙用类似抽象类的感觉
import UIKit public protocol BaseRequsetModel { func url() -> String func header() -> [String: String]? func httpBody() -> [String : Any]? func httpMethod() -> NetworkMethod func paramEncoding() -> Encoding func responseRunningThreadQueue() -> QueueType } extension BaseRequsetModel { func header() -> [String: String]? { return nil } func httpBody() -> [String : Any]? { return nil } func httpMethod() -> NetworkMethod { return .post } func paramEncoding() -> Encoding { return .defaultEncoding} func responseRunningThreadQueue() -> QueueType { return .main } } 这个为什么对这个协议写扩展
对这个协议写扩展是一种 Swift 协议扩展的常见设计模式,主要有以下几个目的:
1. 提供默认实现(主要目的)
swift
extension BaseRequsetModel {
func header() -> [String: String]? { return nil }
func httpMethod() -> NetworkMethod { return .post }
func responseRunningThreadQueue() -> QueueType { return .main }
// ... 其他默认实现
}
好处:遵守该协议的类型不需要实现所有方法,可以选择性地只覆盖需要定制的方法。
使用示例:
swift
// 只需要实现必需的 url() 方法,其他使用默认值
struct LoginRequest: BaseRequsetModel {
func url() -> String {
return "/api/login"
}
// 其他方法使用协议扩展提供的默认实现
}
// 需要定制某些行为
struct UploadRequest: BaseRequsetModel {
func url() -> String { return "/api/upload" }
// 只覆盖需要定制的方法
func httpMethod() -> NetworkMethod { return .put }
func header() -> [String: String]? {
return ["Content-Type": "multipart/form-data"]
}
// 其他方法仍然使用默认实现
}
2. 降低协议遵守的复杂度
如果没有协议扩展:
swift
// 每个遵守协议的类型都必须实现所有方法,即使大部分使用默认值
struct LoginRequest: BaseRequsetModel {
func url() -> String { return "/api/login" }
func header() -> [String: String]? { return nil }
func httpBody() -> [String: Any]? { return nil }
func httpMethod() -> NetworkMethod { return .post }
func paramEncoding() -> Encoding { return .defaultEncoding }
func responseRunningThreadQueue() -> QueueType { return .main }
// 重复编写大量样板代码
}
有协议扩展后:
swift
struct LoginRequest: BaseRequsetModel {
func url() -> String { return "/api/login" }
// 只需要实现必需的方法,其他自动获得默认实现
}
3. 设计意图的表达
这种设计清晰地表达了:
-
url()是必需方法(没有默认实现) -
其他方法都是可选方法(有合理的默认值)
这类似于其他语言中的"抽象类"概念,但 Swift 用"协议 + 扩展"实现。
4. 协议进化性
如果未来需要添加新的方法:
swift
extension BaseRequsetModel {
func timeout() -> TimeInterval { return 30 } // 新增默认方法
func retryCount() -> Int { return 3 } // 新增默认方法
}
现有的所有遵守协议的类型都不会被破坏,它们自动获得这些新方法的默认实现。
5. 合理的默认值选择
提供的默认值都是经过考虑的合理选择:
-
httpMethod(): .post- POST 是最常用的 HTTP 方法 -
responseRunningThreadQueue(): .main- UI 更新通常在主线程 -
header(): nil- 许多请求不需要特殊请求头 -
httpBody(): nil- GET 请求不需要请求体
总结
这种 "协议 + 提供默认实现的扩展" 的设计模式是 Swift 中非常优雅和实用的特性,它:
-
减少样板代码 - 避免在每个类型中重复编写相同的默认实现
-
提高开发效率 - 开发者只需关注需要定制的部分
-
保持灵活性 - 仍然允许在需要时覆盖任何默认行为
-
明确设计意图 - 清晰区分必需和可选的功能
这是一种符合 Swift 协议导向编程(Protocol-Oriented Programming)最佳实践的设计方式。
更多推荐


所有评论(0)