struct Student: Codable { var id: String var name: String var age: Int }
classFoo{ let filePath = "path/to/file" var currentStudent: Student? { get { let decoder = JSONDecoder() let data = Data(contentsOfFile: filePath) return = try? decoder.decode(Student.self, from: data)
} set { let encoder = JSONEncoder() let data = try? encoder.encode(newValue) data.write(to: URL(fileURLWithPath: filePath)) } } }
Cool!
但是一般來說,這個如果資料常常被讀取,被修改的機會比較少,我們通常不會這樣寫。加上如果只考慮單一 process 使用時,可能只要考慮開始結束儲存就好了
structStudent: Codable{ var id: String var name: String var age: Int }
classFoo{ let filePath = "path/to/file"
var studentData = DiskCacheProvider<Student>() var currentStudent: Student? { get { return studentData.getValue() } set { studentData.setValue(newValue) } } }
classDiskCacheProvider<T> { funcgetValue() -> T {
}
funcsetValue(_ newValue: T) {
} }
這樣 DiskCacheProvider 只要負責「資料提供的邏輯和方法」。
再細分「資料提供的邏輯和方法」
仔細想想 DiskCacheProvider 要做什麼事情
何時存取 Cache / File 的邏輯
存取 Cache 資料的方法
存取 File 資料的方法
至少需要上面的幾個事情才能做到整個功能。
存取 Cache / File 資料的方法 可以分別獨立來實作。在實作前,先將概念再抽取出來:
一個有拿取數值和儲存數值的抽象介面
可以設計成:
1 2 3 4 5 6 7
publicprotocolSynchronizedDataProviding: class{ associatedtypeValue funcgetValue()throws -> Value funcsetValue(_ value: Value)throws }
這裡用 Synchronized 是先考量 memory or file 之類的實作體,網路需要等待的介面先不考慮
classStudentMemoryProvider: SynchronizedDataProviding { typealias Value = Student privatevar value: Student
... }
classStudentFileProvider: SynchronizedDataProviding { typealias Value = Student privatevar fileManager: FileManager let filePath = "path/to/file"
... }
classFoo{ let filePath = "path/to/file"
var memoryProvider = StudentMemoryProvider var fileProvider = StudentFileProvider() var studentData = SynchronizedStorageChain<StudentMemoryProvider, StudentFileProvider>(memoryProvider, underlyingProvider: fileProvider)
var currentStudent: Student { get { returntry! studentData.getValue() } set { try! studentData.setValue(newValue) } } }