我目前正在用swift实现我的第一个应用程序,它使用Realm。我真喜欢它!然而,我试图让我的模型变得“好”,但我真的觉得我让它们变得更糟糕了。下面是一个示例模型:
import RealmSwift
class Location : Object {
dynamic var ident = ""
dynamic var package = ""
dynamic var title = ""
dynamic var is_selected = false
let contentSets = List<ContentSet>()
convenience init(ident : String, package: String, title : String, is_selected : Bool) {
self.init()
self.ident = ident
self.package = package
self.title = title
self.is_selected = is_selected
}
override static func primaryKey() -> String? {
return "ident"
}
func save() {
let realm = try! Realm()
try! realm.write {
realm.add(self)
}
}
static func findAll() -> Results<Location> {
return try! Realm().objects(Location)
}
static func findByIdent(ident : String) -> Location?{
return try! Realm().objects(Location).filter("ident == %@", ident).first as Location?
}
static func getSelected() -> Location? {
return try! Realm().objects(Location).filter("is_selected == true").first as Location?
}
func hasContentSetByObject(contentSet : ContentSet) -> Bool {
return self.hasContentSetByString(contentSet.ident)
}
func addContentSet(contentSet: ContentSet) {
let realm = try! Realm()
try! realm.write {
self.contentSets.append(contentSet)
}
}
func isSelected(value: Bool) {
let realm = try! Realm()
let selectedLocation = Location.getSelected()
selectedLocation?.isSelected(false)
try! realm.write {
self.is_selected = value
try! realm.commitWrite()
}
}
func hasContentSetByString(ident : String) -> Bool {
let result = self.contentSets.filter{$0.ident == ident}.count > 0 ? true : false
return result
}}
我的想法是,将所有与领域相关的东西都排除在我的控制器之外。然而,关于更新模型上的数据,我觉得这种方法很糟糕,因为它消除了很多领域的灵活性。
你们是怎么做这种事的?期待您的意见。
致敬,SantoDE
发布于 2016-05-05 21:54:46
您可以保留您的“关注点分离”,而不必牺牲Realm的事务突变模型背后的整个原理,或其查询语法的内部结构。
以下是一些小贴士:
1.减少需要进行错误处理的区域数量。
在您的小示例中,有10个没有错误处理的失败调用(try!)。这是一种代码气味。也就是说,不一定是错误的,但应该会让你更仔细地观察并重新考虑模式。
即使您在每种情况下都要处理错误,这也将是单调乏味且容易出错的。
相反,为什么不尽可能地保持错误处理的本地化,从而产生更简单的代码、更少的重复和更少的未处理错误的机会?
为此,您可以使用依赖项注入,将Realm实例从模型方法中提升出来,并将领域实例传递给需要它的代码部分。
2.避免冗余的类型转换
Realm Swift大量使用了Swift的泛型系统,产生了像这样的冗余动态类型转换:
try! Realm().objects(Location).filter("ident == %@", ident).first as Location?因为下面的代码更加安全,因为没有机会使用错误的类型:
try! Realm().objects(Location).filter("ident == %@", ident).first3.避免冗余的写入提交
这段代码:
try! realm.write {
self.is_selected = value
try! realm.commitWrite()
}是不正确的,因为Realm.write(_:)调用会在调用传入的闭包之后自动调用Realm.commitWrite()。所以只需替换为以下内容:
try! realm.write {
self.is_selected = value
}4.避免离开Realm的查询系统
像这样的代码强制Realm将其所有对象物化为Swift对象,这执行起来非常糟糕:
let result = self.contentSets.filter{$0.ident == ident}.count > 0 ? true : false
return result相反,您应该更喜欢Realm的本机查询系统,它针对Realm数据进行了优化:
return !contentSets.filter("ident == %@", ident).isEmpty一般来说,我还想说,如果您发现自己以关注点分离的名义编写了大量代码,那么您真正获得的是什么?
https://stackoverflow.com/questions/37006945
复制相似问题