面向协议编程的思维,在
Swift
开发中非常非常重要!可以说如果你用好了POP
那么你的项目绝对逼格不是一个level
下面我们通过解决OOP
问题的思路展开分析
1. POP
解决横切关注点
横切关注点 (Cross-Cutting Concerns)
那就是我们很难在不同继承关系的类里共用代码! 现在我们通过面向协议的方式,任何遵循协议
的,都可以默认添加 name
属性以及sayHello()
方法!
protocol GTProtocl {
/// 协议属性
var name: String {get}
/// 协议方法
func sayHello()
}
- 但是这里还有一个问题:缺乏实现!如果这样提供声明,我还需要在每一个类里面实现,有很多时候其实这些方法都是共有,不需要太多特定实现
- 幸好在 WWDC 2015 和
Swift 2
发布时,Apple
为协议引入了一个新特性一 协议扩展 它为Swift 语言
带来了一次革命性
的变化。
struct GTTeacher: GTProtocl{
var name: String
func sayHello() {
print("你好")
}
}
- 通过
协议
定义,提供实现
的入口,遵循协议
的类型需要对其进行实现 - 协议扩展,为入口提供默认实现。根据入口提供额外实现
这样的操作有什么作用了? 一 万物皆
GT
// 声明协议
extension GTCompatible {
/// Reactive extensions.
public static var gt: GTRxSwift.Reactive<Self>.Type
/// Reactive extensions.
public var gt: GTRxSwift.Reactive<Self>
}
// NSObject 实现
extension NSObject : GTCompatible { }
- 这样完美实现了
万物皆GT
的特性 - 然后通过
GTCompatible
引申到Reactive
响应式类
或者结构体
- 最后通过不断拓展
Reactive
的能力,就能完美切合
2.POP
解决动态派发安全性
对于没有实现 GTProtocl
的类型,编译器
将返回错误,因此不存在消息误发送的情况;
// Compiler Error:
// 'GTTeacher' does not conform to protocol 'GTProtocl'
// protocol requires function 'sayHello()'
3. POP
解决菱形缺陷
最后我们看看多继承
。多继承
中存在的一个重要问题是菱形缺陷,也就是子类无法确定使用哪个父类的方法。在协议的对应方面,这个问题虽然依然存在,但却是可以唯一安全地确定的。
这里很遗憾POP
在 解决菱形缺陷
这一点上也存在同样的BUG
, 因为多个协议存在相同的协议属性、协议方法,遵循者也是无法确定的!⚠️ 我们在平时开发中一定要尽量规避同名协议遵循问题,我们在模块划分上面一定要做做到彻底,尽管 Swift 还不能很好地处理多个协议的冲突 但是我们可以在协议层功能抽层严格机智处理上浮与下沉功能。
举个例子:
我们刚刚是不是做了 GTCompatible
, 它是我们功能的入口,万物皆GT
,进来,那么这层协议只需要提供入口就完毕
同时提供接口过度能力,把 GTReactiveCompatible
的 GT
过度到 Reactive层
extension GTReactiveCompatible {
/// Reactive extensions.
public static var gt: Reactive<Self>.Type {
get { return Reactive<Self>.self }
set {// this enables using Reactive to "mutate" base type }
}
/// Reactive extensions.
public var gt: Reactive<Self> {
get { return Reactive(self) }
set { // this enables using Reactive to "mutate" base object }
}
}
-
Reactive层
, 根据业务划分开来,达到逻辑代码下沉效果!
public struct Reactive<Base> {
public let base: Base
public init(_ base: Base) {
self.base = base
}
}
- 根据
Reactive
里面关联的Base 类型
来确定不同的响应式功能
- 比如:
extension Reactive where Base: UISwitch
其中UISwitch
可以+ 换成UITableView、UITextField、UIView ...
不断业务下沉!
相信到这里你已经感受到了面向协议编程的方便之处,但是还有一个非常重要的特性没有展现出来就是 一 耦合度大大降低,代码分层,逻辑更清晰
网友评论