Swift笔记 - 17.面向协议编程
Swift笔记 - 17.面向协议编程
面向协议编程
- 面向协议编程(ProtocolOriented Programming,简称POP)
- 是Swift的一种编程范式,Apple于2015年WWDC提出
- 在Swift的标准库中,能见到大量POP的影子
- 同时,Swift也是一门面向对象的编程语言(Object Oriented Programming,简称OOP)
- 在Swift开发中,0OP和POP是相辅相成的,任何一方并不能取代另一方
-
POP能弥补OOP一些设计上的不足
- 利用协议实现前缀效果
var string = "123fdsf434"
print(string.mj.numberCount())
struct MJ<Base> {
let base: Base
init(_ base: Base) {
self.base = base
}
}
protocol MJCompatible {}
extension MJCompatible {
static var mj: MJ<Self>.Type {
get { M]<Self>.self }
set {}
}
var mi: MJ<Self> {
get { MJ(self) }
set {}
}
}
extension String: MJCompatible {}
extension MJ 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: MJCompatible {}
extension MJ where Base: Person {
func run() {}
static func test() {}
}
Person.mj.test()
Student.mi.test()
let p = Person()
p.mi.run()
let s = Student()
s.mi.run()
var s1: String = "123fdsf434"
var s2: NSString = "123fds f434"
var s3: NSMutableString = "123fdsf434"
print(s1.mj.numberCount())
print(s2.mj.numberCount())
print(s3.m.numberCount())
extension String: MJCompatible {}
extension NSString: MJCompatible {}
extension MJ 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
}
}
代码实现优化过程
var str = "1234test1234"
func numberCount (_ str: String) -> Int {
var count = 0
for c in str {
if ("0"... "9").contains(c) {
count += 1
}
}
return count
}
print (numberCount(str))
for
循环优化
var str = "1234test1234"
func numberCount (_ str: String) -> Int {
var count = 0
for c if str where ("0"..."9").contains(c) {
count += 1
}
print(numberCount(str))
使用extension
优化
var str = "123rrr"
extension String {
var numberCount: Int {
var count = 0
for c in self where ("0"..."9").contains(c) {
count += 1
}
return count
}
}
print(str.numberCount)
定义结构体优化
struct MJ {
var string: String
init(_ string: String) {
self.string = string
}
var numberCount: Int {
var count = 0
for c in string where (""..."9" ).contains (c) {
count += 1
}
return count
}
extension String {
var mj: MJ ( return[MJ(self) }
}
print ("123kkk" .mj.numberCount)
加入MJ extension
优化
struct MJ<Base> {
var base: Base
init(_ base: Base) {
self.base = base
}
}
extension String
var mj: MJ<String> { MJ(self) }
}
class Person ()
extension Person {
var mi: MJ<Person> { MJ(self) }
}
//扩展
extension MJ where Base == String {
var numberCount: Int {
var count = e
for c in base where ("®"..."9").contains (c) {
count += 1
}
return count
}
}
extension MJ where Base: Person {
func run() {}
}
var person = Person()
person.mj.rund)
//"123xxx".mj.numberCount
再优化,以支持静态扩展
struct MJ<Base> {
var base: Base
init(_ base: Base) {
self.base = base
}
}
extension String {
var mj: MJ<String> { MJ(self) }
static var mj: MJ<String>.Type { MJString>.self }
}
class Person {
extension Person {
var mj: MJ<Person> { MJ(self) }
}
//扩展
extension MJ where Base == String {
var numberCount: Int {
var count = 0
for c in base where ("0"..."9").contains (c) {
count += 1
}
return count
}
}
extension MJ where Base: Person {
func run() {}
}
var person = Person()
person.mj.run()
//"123xxx" .mj.numberCount
再度优化让它支持 mutating
方法
//前缀类型
struct MJ<Base> {
var base: Base
init( base: Base) {
self.base = base
}
}
利用协议扩展前缓属性
protocol MJCompatible {}
extension MJCompatible {
static var mj: MJ<Self>.Type {
set {}
get { MJ<Self>.self }
}
var mj: MJ<Self> {
set {}
get { MJ(self) }
}
}
//给宇符串扩展功能
//让String拥有mj前缀属性
extension String: MJCompatible {}
//给String.mj.String().mj前缀扩展功能
extension MJ where Base == String {
var numberCount: Int {
var count = 0
for c in base where ("0"..."9").contains(c) {
count += 1
}
return count
}
mutating func run() {}
static func test() {}
}
var str = "123213"
str.mj.run()
再度优化
// 给 String.mj.String().mj前缀扩展功能
extension MJ where Base: ExpressibleByStringLiteral {
var numberCount: Int {
var count = 0
for c in (base as! Strina) where ("0"... "9").contains(c) {
count += 1
}
return count
}
}
var str1 = "123xxx"
var str2: NSString = "123xxx"
var str3: NSMutableString = "123xxx"
print(str1.mj.numberCount)
print(str2.mj.numberCount)
print(str3.mj.numberCount)
利用协议实现类型判断
func isArray(_ value: Any) -> Bool { value is [Any] }
isArray( [1, 2] )
isArray( ["1", 2] )
isArray( NSArray() )
isArray(NSMutableArray())
// output:
// true
// true
// true
// true
protocol ArrayType {}
extension Array: ArrayType {}
extension NSArray: ArrayType {}
//因为实现了ArrayType协议,isArrayType的实现是根据协议来判断,所以都会返回true.
func isArrayType(_ type: Any.Type) -> Bool { type is ArrayType.Type }
isArrayType([Int].self)
isArrayType([Any].self)
isArrayType(NSArray.self)
isArrayType(NSMutableArray.self)
// output:
// true
// true
// true
// true