实现 Drawable
协议及协议扩展
// 定义 Drawable 协议
protocol Drawable {
func draw()
}
// 协议扩展,提供默认绘制方法
extension Drawable {
func draw() {
print("默认的绘制方法")
}
}
// 圆形结构体,遵循 Drawable 协议
struct Circle: Drawable {
var radius: Double
// 可以选择使用默认的 draw 方法,也可以重写
func draw() {
print("绘制半径为 \(radius) 的圆形")
}
}
// 矩形结构体,遵循 Drawable 协议
struct Rectangle: Drawable {
var width: Double
var height: Double
// 使用默认的 draw 方法
}
基于协议扩展设计在抽象设计模式中的优势
- 代码复用:通过协议扩展为遵循协议的类型提供默认实现,减少了重复代码。例如,多个图形类型可能都需要一些基本的绘制准备工作,这些工作可以放在协议扩展的默认方法中,而不必在每个具体类型中重复实现。
- 灵活性与可扩展性:新的类型只要遵循
Drawable
协议,就能自动获得协议扩展中的默认方法。如果需要添加新的功能,只需在协议扩展中添加新的方法,所有遵循该协议的类型都会自动获得这个新功能,无需对每个具体类型进行修改。
- 解耦与松耦合:具体类型只需要关注自身特有的属性和方法,与通用的绘制逻辑解耦。这样可以让代码结构更清晰,易于维护和修改。不同的图形类型之间通过协议联系在一起,而不是通过继承关系,降低了类型之间的耦合度。
可能带来的问题
- 命名冲突:如果不同的协议扩展为相同类型提供了同名的默认方法,可能会导致命名冲突。这需要在设计协议和协议扩展时仔细规划方法命名,避免冲突。
- 调试困难:由于默认方法在协议扩展中实现,当出现问题时,可能不太容易定位到具体的错误位置。尤其是当多个协议扩展相互影响时,调试难度会增加。
- 协议污染:如果协议扩展中添加了过多的默认方法,可能会导致协议变得庞大和复杂,使得遵循该协议的类型被迫承担一些不必要的功能,这被称为“协议污染”。需要合理控制协议扩展中的功能,确保协议的简洁性和针对性。