我在应用程序中使用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)
答案 0 :(得分:4)
这是一个完全可靠的设计模式。开发人员从代码中抽象数据层API的方式非常普遍,以防他们需要将其切换出来。
回答你的问题:
Realm
对象实例在内部进行缓存,因此您可以轻松地多次调用let realm = try! Realm()
。refresh()
。主线程上的Realm实例会在运行循环的每次迭代中自动刷新,因此如果您希望在后台线程上进行更改,或者需要在当前运行之前访问更改,则只需要调用refresh()
循环已经完成。