&引用;“正确”;swift中的领域模型?

&引用;“正确”;swift中的领域模型?,swift,realm,Swift,Realm,我目前正在swift中实现我的第一个应用程序,它使用领域。我真的很喜欢!然而,我试图使我的模型“好”,但我真的觉得我使他们更糟糕的领域。下面是一个示例模型: import RealmSwift class Location : Object { dynamic var ident = "" dynamic var package = "" dynamic var title = "" dynamic var is_selected = false let contentSets = Lis

我目前正在swift中实现我的第一个应用程序,它使用领域。我真的很喜欢!然而,我试图使我的模型“好”,但我真的觉得我使他们更糟糕的领域。下面是一个示例模型:

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
}
导入RealmSwift
类位置:对象{
动态变量ident=“”
动态变量包=“”
动态变量title=“”
动态变量被选中=错误
让contentset=List()
便利初始化(标识:String,包:String,标题:String,is_selected:Bool){
self.init()
self.ident=ident
self.package=package
self.title=标题
self.is_selected=是否已选择
}
重写静态func primaryKey()->字符串{
返回“ident”
}
func save(){
让realm=try!realm()
试试看!写吧{
realm.add(self)
}
}
静态func findAll()->结果{
返回try!Realm().对象(位置)
}
静态函数findByIdent(标识:字符串)->位置{
返回try!Realm()?
}
静态函数getSelected()->位置{
返回try!Realm()?
}
func hasContentSetByObject(contentSet:contentSet)->Bool{
返回self.hasContentSetByString(contentSet.ident)
}
func addContentSet(contentSet:contentSet){
让realm=try!realm()
试试看!写吧{
self.contentSet.append(contentSet)
}
}
func isSelected(值:Bool){
让realm=try!realm()
让selectedLocation=Location.getSelected()
selectedLocation?.isSelected(假)
试试看!写吧{
self.is_selected=值
试试看!realm.commitWrite()
}
}
func hasContentSetByString(标识:字符串)->Bool{
让result=self.contentSets.filter{$0.ident==ident}.count>0?true:false
返回结果
}
}

我的想法是,让所有与领域相关的东西远离我的控制器。然而,关于更新模型上的数据,我觉得这种方法很糟糕,因为它抹去了很多领域的灵活性

你们是怎么做的?期待您的意见

问候,, SantoDE

您可以保留您的“关注点分离”,而不必牺牲Realm事务性突变模型背后的全部原理,或其查询语法的内部结构

以下是一些提示:

1.尽量减少需要进行错误处理的区域数量。 从您的小样本中,有10个可失败的呼叫(
try!
)没有错误处理。这是一种代码气味。如中所述,不一定是错误的,但应该让您仔细观察并重新考虑该模式

即使您在每种情况下都处理错误,这也将是乏味且容易出错的

相反,为什么不让错误处理尽可能本地化,从而产生更简单的代码、更少的重复和更少的未处理错误的机会呢

您可以通过使用依赖项注入,将
领域
实例从模型方法中提升出来,并将领域实例传递给代码中需要它的部分来实现这一点

2.避免冗余类型转换 Realm Swift大量使用Swift的泛型系统,产生如下动态强制转换:

try! Realm().objects(Location).filter("ident ==  %@", ident).first as Location?
因为以下类型更安全,因为没有机会使用错误的类型:

try! Realm().objects(Location).filter("ident ==  %@", ident).first
3.避免冗余写提交 此代码:

try! realm.write {
  self.is_selected = value
  try! realm.commitWrite()
}
不正确,因为调用传入的闭包后,
Realm.write(:)
调用会自动调用
Realm.commitWrite()
。因此,只需替换为以下内容:

try! realm.write {
  self.is_selected = value
}
4.避免离开领域的查询系统 这样的代码迫使Realm将其所有对象具体化为Swift对象,但性能非常差:

let result = self.contentSets.filter{$0.ident == ident}.count > 0 ? true : false
return result
相反,您应该更喜欢Realm的本机查询系统,该系统针对Realm数据进行了优化:

return !contentSets.filter("ident == %@", ident).isEmpty


总的来说,我还要说,如果你发现自己以关注点分离的名义编写了大量代码,那么你真正得到了什么?

非常感谢@jpsim!这真的很有帮助:)这正是我期待的反馈。然而,现在我正试图通过使用Swinject使事情顺利进行。我正在努力让它在模型课上运行。因为,当我尝试早期注入模型时,我可能没有所有需要的属性(ident、package…)。你们是怎么解决的?我的想法是要有一个realmService,我将它注入到模型中,以分离事物。这(目前)对我来说似乎很难。