美文网首页程序员
对swift中的扩展进行"分组"

对swift中的扩展进行"分组"

作者: fuadam1982 | 来源:发表于2016-12-10 12:11 被阅读52次

    在swift中对类和struct进行扩展或使用协议扩展(本质是mixin),是非常简单且实用的语法。但是语法糖太好用了就可能乱用并产生混乱(比如,团队中对时间处理做了很多的扩展)。这两天看ReactiveSwift源码学到了一种比较好的写法来解决这个问题。先看demo:

    // 我们有两个Model类
    class MyModel {
        var tableName: String {
            return "tbl_model_1"
        }
        var itemA: Int?
        var itemB: String?
    }
    
    class MyModel2 {
        var itemA: Bool?
        var itemB: [Int]?
    }
    
    // 需要增加Log功能的协议
    protocol Loggable { }
    extension Loggable {
        // 利用Self约束,限定使用log功能的扩展包装类
        var logger: Logger<Self> {
            return Logger(self)
        }
    }
    // 我们将所有和log相关的扩展统一用Logger包装
    struct Logger<Base: Loggable> {
        var base: Base
        init(_ base: Base) {
            self.base = base
        }
    }
    // 针对MyModel进行log功能的定制扩展
    extension MyModel: Loggable { }
    extension Logger where Base: MyModel {
        func dumpForDb() {
            print("tableName:\(base.tableName), itemA:\(base.itemA), itemB:\(base.itemB)")
        }
    }
    // 针对MyModel2进行log功能的定制扩展
    extension MyModel2: Loggable { }
    extension Logger where Base: MyModel2 {
        func dumpSelf() {
            dump(base)
        }
    }
    
    // 具体使用
    let my1 = MyModel()
    let my2 = MyModel2()
    my1.logger.dumpFOrDb()
    my2.logger.dumpSelf()
    

    这里面的基本思路就是利用一个struct去包装要进行扩展的具体类或struct,所以my1.logger等同于Logger(my1)。有了这个小技巧我们的代码就可以写的更加清晰了,比如有:

    my1.mapping.toJSON()    // Model映射扩展
    my1.db.save()           // 数据库操作扩展
    my1.net.request()       // 网络操作扩展
    

    是不是很好用!

    相关文章

      网友评论

        本文标题:对swift中的扩展进行"分组"

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