面向协议编程
Protocol Oriented Programming
简称POP
.是Swift
的一种编程范式.同时Swift
也是一门面向对象的编程语言Object Oriented Programming
简称OOP
.在Swift
中OOP
和POP
是相辅相成的.POP
能弥补OOP
一些设计上的不足.
POP的注意点
- 优先考虑创建协议,而不是父类
基类
- 优先考虑值类型
struct enum
,而不是引用类型class
- 巧用协议的扩展功能
- 不要为了面向协议而使用协议
利用协议实现前缀效果
import UIKit
struct LDWrapper<Base> {
let base: Base
init(_ base: Base) {
self.base = base
}
}
protocol LDCompatible {}
extension LDCompatible {
static var ld: LDWrapper<Self>.Type {
get { LDWrapper<Self>.self }
set { }
}
var ld: LDWrapper<Self> {
get { LDWrapper(self) }
set {}
}
}
extension String: LDCompatible {}
extension LDWrapper where Base == String {
func numberCount() -> Int {
var count = 0
for c in base where ("0" ... "9").contains(c) {
count += 1
}
return count
}
}
var string = "123fds434"
print(string.ld.numberCount())
Base: 类
import UIKit
struct LDWrapper<Base> {
let base: Base
init(_ base: Base) {
self.base = base
}
}
protocol LDCompatible {}
extension LDCompatible {
static var ld: LDWrapper<Self>.Type {
get { LDWrapper<Self>.self }
set { }
}
var ld: LDWrapper<Self> {
get { LDWrapper(self) }
set {}
}
}
extension String: LDCompatible {}
extension LDWrapper where Base == String {
func numberCount() -> Int {
var count = 0
for c in base where ("0" ... "9").contains(c) {
count += 1
}
return count
}
}
class Person { }
class Student: Person { }
extension Person: LDCompatible { }
extension LDWrapper where Base: Person {
func run() { }
static func test() { }
}
Person.ld.test()
Student.ld.test()
let p = Person()
p.ld.run()
let s = Student()
s.ld.run()
Base: 协议
import UIKit
struct LDWrapper<Base> {
let base: Base
init(_ base: Base) {
self.base = base
}
}
protocol LDCompatible {}
extension LDCompatible {
static var ld: LDWrapper<Self>.Type {
get { LDWrapper<Self>.self }
set { }
}
var ld: LDWrapper<Self> {
get { LDWrapper(self) }
set {}
}
}
extension String: LDCompatible {}
extension LDWrapper where Base == String {
func numberCount() -> Int {
var count = 0
for c in base where ("0" ... "9").contains(c) {
count += 1
}
return count
}
}
class Person { }
class Student: Person { }
extension Person: LDCompatible { }
extension LDWrapper where Base: Person {
func run() { }
static func test() { }
}
var s1: String = "123fds434"
var s2: NSString = "123fds434"
var s3: NSMutableString = "123fds434"
print(s1.ld.numberCount())
print(s2.ld.numberCount())
print(s3.ld.numberCount())
extension String: LDCompatible {}
extension NSString: LDCompatible {}
extension LDWrapper where Base: ExpressibleByStringLiteral {
func numberCount() -> Int {
let string = base as! String
var count = 0
for c in string where ("0" ... "9").contains(c) {
count += 1
}
return count
}
}
利用协议实现类型判断
func isArray(_ value: Any) -> Bool {
value is [Any]
}
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(isArray([1,2]))
print(isArray(["1",2]))
print(isArray(NSArray()))
print(isArray(NSMutableArray()))
}
}
protocol ArrayType { }
extension Array: ArrayType {}
extension NSArray: ArrayType {}
func isArrayType(_ type: Any.Type) -> Bool {
type is ArrayType.Type
}
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//true
print(isArrayType([Int].self))
print(isArrayType([Any].self))
print(isArrayType(NSArray.self))
print(isArrayType(NSMutableArray.self))
}
}