美文网首页
25-面向协议编程

25-面向协议编程

作者: bytebytebyte | 来源:发表于2020-11-01 00:27 被阅读0次
    //面向协议编程1-7
    /*
     1.面向协议编程
     面向协议编程Protocol Oriented Programming,POP是swift的一种编程范式,Apple于2015年WWDC提出,在swift的标准库中,能见到大量POP的影子。同时,swift也是一门面向对象的编程语言Object Oriented Programming,OOP,在swift开发中,OOP和POP是相辅相成的,任何一方并不能取代另一方,POP能弥补OOP设计上的不足.
     2.回顾OOP
     OOP的三大特性:封装、继承、多态。
     继承的经典使用场合:当多个类(比如A、B、C类)具有很多共性时,可以将这些共性抽取到一个父类中(比如D类),最后A、B、C类继承D类。
     3.OOP的不足
     但有些问题,使用OOP并不能很好解决,比如如何将BVC、DVC的公共方法run抽取出来?
     class BVC: UIViewController {
         func run() {
             print("run")
         }
     }
     class DVC: UITableViewController {
         func run() {
             print("run")
         }
     }
     基于OOP想到的一些解决方案?
     1.将run方法放到另一个对象中,然后BVC、DVC拥有对象A的属性,多了一些额外的关系。
     2.将run方法增加到UIViewController分类中,UIViewController会越来越臃肿,而且会影响它的其他所有子类。
     3.将run方法抽取到新的分类、采用多继承?(C++支持多继承),会增加程序设计复杂度,产生菱形继承问题,需要开发者额外解决。
     */
    //4.POP的解决方案
    import UIKit
    protocol Runnable {
        func run()
    }
    extension Runnable {
        func run() {
            print("run")
        }
    }
    class BVC: UIViewController, Runnable {}
    class DVC: UITableViewController, Runnable {}
    
    //5.POP的注意点
    /*
     a.有限考虑创建协议,而不是父类(基类)。
     b.优先考虑值类型(struct、enum),而不是引用类型。
     c.巧用协议的拓展功能。
     d.不要为了面向协议而使用协议。
     */
    
    //6.利用协议实现前缀效果
    //前缀类型
    struct MJ<Base> {
        var base: Base
        init(_ base: Base) {
            self.base = base
        }
    }
    //利用协议拓展前缀属性
    protocol MJCompatibble {}
    extension MJCompatibble {
        static var mj: MJ<Self>.Type {
            set {} //为了mutating语法能通过
            get { MJ<Self>.self }
        }
        var mj: MJ<Self> {
            set {}
            get { MJ(self) }
        }
    }
    //给字符串拓展功能
    //让String拥有mj前缀属性
    extension String: MJCompatibble {}
    extension NSString: MJCompatibble {}
    //给String.mj、String().mj前缀拓展功能
    extension MJ where Base: ExpressibleByStringLiteral {
        var numberCount: Int {
            var count = 0
            for c in (base as! String) where ("0"..."9").contains(c) {
                count += 1
            }
            return count
        }
        mutating func run() {}
        static func test() {}
    }
    var str1 = "123123"
    var str2: NSString = "123123"
    var str3: NSMutableString = "123123"
    str1.mj.run() //"123123"mj.run() 报错
    print(str1.mj.numberCount)
    print(str2.mj.numberCount)
    print(str3.mj.numberCount)
    
    //7.利用协议实现类型判断
    func isArray(_ value: Any) -> Bool {
        value is Array<Any> //var is [Any]
    }
    print(isArray([1, 2])) //true
    print(isArray(["1", 2])) //true
    print(isArray(NSArray())) //true
    print(isArray(NSMutableArray())) //true
    print(isArray("123123")) //false
    
    protocol ArrayType {}
    extension Array: ArrayType {}
    extension NSArray: ArrayType {}
    func isArrayType(_ type: Any) -> Bool {
        type is ArrayType.Type
    }
    print(isArrayType([Int].self)) //true
    print(isArrayType([Double].self))//true
    print(isArrayType([Any].self))//true
    print(isArrayType(NSArray.self))//true
    print(isArrayType(NSMutableArray.self))//true
    print(isArrayType(String.self))//false
    

    相关文章

      网友评论

          本文标题:25-面向协议编程

          本文链接:https://www.haomeiwen.com/subject/pfwfmktx.html