从“继承”到“组合”:iOS开发范式正在发生一场静默革命
早期iOS开发的核心语言是Objective-C,它天然地鼓励类继承和层级深重的抽象。我们习惯用UIViewController子类承载所有逻辑,用Facade模式包裹网络层,用Base基类实现公共方法。然而,随着Swift的成熟与SwiftUI的出现,一种更接近函数式与协议导向的组合式开发方式正在兴起。这种变化看似只是语言和框架的迭代,其本质却是从“类型层级的深度”转向“行为片段的重组”——这是开发范式的一次根本性迁移。
传统UIKit开发中,UIViewController是天然的上帝类根源。开发者倾向于将页面生命周期、数据请求、业务逻辑、事件处理全部塞入一个ViewController,然后通过继承基类来复用功能。这种方式在业务简单时效率极高,但一旦业务复杂化,继承树会迅速膨胀:BaseViewController、BaseTableViewController、BaseNetworkViewController……每一层引入隐式依赖,子类无法轻易剥离父类行为。与此同时,Swift的协议导向编程提供了一种完全不同的思路:用协议定义职责,用extension提供默认实现,用值类型或轻量类型组合成完整行为。这种组合式设计可以让类变得扁平,职责清晰,测试时仅需模拟最小依赖,而无需构造庞大的继承栈。
SwiftUI将这种组合式哲学推向了系统层面。它不再有UIViewController生命周期,而是通过View的body聚合小粒度的子视图,使用@State、@Binding、@ObservableObject管理状态流。修饰符(Modifier)的应用本质上就是函数式组合:Text("Hello").font(.title).foregroundColor(.red)——每个修饰符返回新的视图,而非修改原对象。这种不可变数据流的风格迫使开发者从“被动响应事件”转向“声明式状态映射”。然而,UIKit并没有消失,大量的生产级应用仍基于UIKit。真正的挑战在于如何在混合架构中平衡两种范式:是继续用UIKit做复杂交互,还是用SwiftUI渲染整体界面?独立观点认为,完全抛弃UIKit是短视的,苹果通过UIHostingController和UIViewRepresentable已经承认了过渡期的必要性。核心的转变不是UI层,而是应用状态管理:使用单向数据流(如Reducer模式)或结构化的Observation框架,使得底层逻辑可以独立于UI框架存在。
更深层来看,这场革命源于Swift语言本身对“值语义”的强化。结构体(struct)、枚举(enum)和协议(protocol)的组合能力日益提升,而类(class)被逐步边缘化为需要共享同步状态的场合。组合式开发意味着开发者要放弃对“对象身份”的执念,转而思考“值如何变换”。例如,一个游戏中的玩家状态不再是可变对象,而是一个struct PlayerState,由外部系统通过函数进行不可变更新。这种思路不仅在SwiftUI中有效,在UIKit项目中同样可以借助CGAffineTransform、RxSwift或Swift Concurrency实现范式升级。摒弃继承而选择组合,不是代码风格的偏好问题,而是一种更适应Swift并发模型与类型系统的选择——它能让每个组件的可测试性、可复用性和可解释性获得质的提升。
最终,iOS开发的未来不会是SwiftUI与UIKit的对决,而是两种思维模式在开发者社区中的融合与重塑。独立开发者与大型团队都需要意识到:继承仍适用于少数真正的“is-a”关系,而组合应用于绝大多数“has-a”与“can-do”场景。我们必须从“设计一套基类”转向“定义一组协议”,从“搭建view层级”转向“构建状态流”,从“代码的树形重用”转向“功能的单元化装配”。这场静默革命已经由Swift Language和SwiftUI框架在底层推动,但真正落地需要每一位开发者在工程实践中逐步调整自己的抽象直觉。停止写下一个BaseViewModel,转而定义一个个Pure Function和Small Protocol——这才是iOS开发现代化的正确打开方式。