在swift中對(duì)類(lèi)和struct進(jìn)行擴(kuò)展或使用協(xié)議擴(kuò)展(本質(zhì)是mixin)呻纹,是非常簡(jiǎn)單且實(shí)用的語(yǔ)法冗栗。但是語(yǔ)法糖太好用了就可能亂用并產(chǎn)生混亂(比如灯谣,團(tuán)隊(duì)中對(duì)時(shí)間處理做了很多的擴(kuò)展)怠苔。這兩天看ReactiveSwift源碼學(xué)到了一種比較好的寫(xiě)法來(lái)解決這個(gè)問(wèn)題吱七。先看demo:
// 我們有兩個(gè)Model類(lèi)
class MyModel {
var tableName: String {
return "tbl_model_1"
}
var itemA: Int?
var itemB: String?
}
class MyModel2 {
var itemA: Bool?
var itemB: [Int]?
}
// 需要增加Log功能的協(xié)議
protocol Loggable { }
extension Loggable {
// 利用Self約束刚盈,限定使用log功能的擴(kuò)展包裝類(lèi)
var logger: Logger<Self> {
return Logger(self)
}
}
// 我們將所有和log相關(guān)的擴(kuò)展統(tǒng)一用Logger包裝
struct Logger<Base: Loggable> {
var base: Base
init(_ base: Base) {
self.base = base
}
}
// 針對(duì)MyModel進(jìn)行l(wèi)og功能的定制擴(kuò)展
extension MyModel: Loggable { }
extension Logger where Base: MyModel {
func dumpForDb() {
print("tableName:\(base.tableName), itemA:\(base.itemA), itemB:\(base.itemB)")
}
}
// 針對(duì)MyModel2進(jìn)行l(wèi)og功能的定制擴(kuò)展
extension MyModel2: Loggable { }
extension Logger where Base: MyModel2 {
func dumpSelf() {
dump(base)
}
}
// 具體使用
let my1 = MyModel()
let my2 = MyModel2()
my1.logger.dumpFOrDb()
my2.logger.dumpSelf()
這里面的基本思路就是利用一個(gè)struct去包裝要進(jìn)行擴(kuò)展的具體類(lèi)或struct羡洛,所以my1.logger等同于Logger(my1)。有了這個(gè)小技巧我們的代碼就可以寫(xiě)的更加清晰了藕漱,比如有:
my1.mapping.toJSON() // Model映射擴(kuò)展
my1.db.save() // 數(shù)據(jù)庫(kù)操作擴(kuò)展
my1.net.request() // 網(wǎng)絡(luò)操作擴(kuò)展
是不是很好用欲侮!