我在应用程序中使用Realm并且我正在尝试尽可能地抽象,以便将来我可以交换数据库提供程序而不需要太多更改.
虽然我关注以下内容,但这种模式运作良好.
我的目的是否有更好的设计模式?
public struct BookDataLayer: BookDataLayerProvider {
func isBookAvailable(bookIdentifier: String) throws -> Bool {
let database = try getDatabase()
return !database.objects(Book).filter("identifier = %@", bookIdentifier).isEmpty
}
func createOrUpdateBook(bookIdentifier: String, sortIndex: Int) throws {
let book = Book()
Book.bookIdentifier = bookIdentifier
Book.sortIndex = sortIndex
try create(book, update: true)
}}
protocol BookDataLayerProvider : DataAccessLayer {
func isBookAvailable(bookIdentifier: String) throws -> Bool
func createOrUpdateBook(bookIdentifier: String, sortIndex: Int) throws n}
extension DataAccessLayer {
func getDatabase() throws -> Realm {
do {
let realm = try Realm()
// Advance the transaction to the most recent state
realm.refresh()
return realm
} catch {
throw DataAccessError.DatastoreConnectionError
}
}
func create(object: Object, update: Bool = false) throws {
let database = try self.getDatabase()
do {
database.beginWrite()
database.add(object, update: update)
// Commit the write transaction
// to make this data available to other threads
try database.commitWrite()
} catch {
throw DataAccessError.InsertError
}
}}
// Usage
let bookDataLayer = BookDataLayer()
bookDataLayer.isBookAvailable("4557788")
bookDataLayer.createOrUpdateBook("45578899", 10)
Run Code Online (Sandbox Code Playgroud)这是一个完全可靠的设计模式。开发人员从他们的代码中抽象出数据层 API 的方式是很常见的,以防他们需要将其切换出来。
针对您的问题:
Realm对象实例在内部缓存,因此您可以轻松地let realm = try! Realm()以很少的开销多次调用。refresh()每次使用 Realm 实例时都调用它。主线程上的 Realm 实例会在运行循环的每次迭代中自动刷新,因此您只需要refresh()在期望后台线程上的更改时调用,或者需要在当前运行循环完成之前访问更改。