在Swift中,**协议导向编程(POP)**受到了很大的重视。POP的主要思想是从协议(接口)开始设计架构,而不是从基类开始。协议允许通过多个链条继承行为,从而降低代码的耦合性。
Swift允许协议具有默认实现(通过扩展),这有助于在没有类层次结构的情况下重用代码。 经典的面向对象编程依赖于类之间的继承,这限制了只能有一个继承链。POP摆脱了这些限制,允许组合和扩展。
代码示例:
protocol Drivable { func drive() } extension Drivable { func drive() { print("Driving forward!") } } struct Car: Drivable {} let car = Car() car.drive() // 会输出: Driving forward!
可以在协议扩展中添加存储属性吗?
回答: 不可以,在协议的扩展中不能添加存储属性,只能添加计算属性和方法。例如,
// 错误! extension Drivable { var speed: Int = 0 // 编译错误: 扩展不能包含存储属性 }
故事
在一个大型项目中,开发人员试图通过协议扩展添加存储属性以跟踪状态。代码编译时发生错误,因此不得不在冲刺的高峰期紧急重构架构,以使用第三方解决方案与objc_get/setAssociatedObject结合使用——这降低了代码的可读性。
故事
在项目中实现了一个基础类以适应不同类型的实体,并通过协议使用多重继承。开发人员混淆了扩展中的默认实现行为,并试图在结构体中重写该方法,期待调用的是结构体中的实现。最终很难追踪方法的调用顺序。
故事
在模块扩展时使用协议进行责任分离,但由于对POP缺乏经验,开发人员未能在协议之间明确依赖关系。这导致了代码重复和在大规模开发团队中合并多个扩展时出现接口冲突。