在Cocoa Touch框架中使用Realm时的模式



当在Cocoa Touch框架内使用令人惊叹的Realm数据库时,这是一个代码模式/设计问题。具体来说,是一个将作为茧分发的框架。

假设我在一个框架内有一些领域对象,我正在构建

public class Dog: Object {
@objc public private(set) dynamic var name: String?
public let age = RealmOptional<Int>()
public private(set) var owner: Person?
}
public class Person: Object {
@objc public private(set) dynamic var name: String?
public private(set) var dogs = LinkingObjects(fromType: Dog.self, property: "owner")
}

现在,我希望我的框架的使用者能够与这些对象进行交互。我不想用MVVM模式来抽象这些,因为我希望我的框架的用户能够利用一些很棒的Realm功能,比如查询、排序,最重要的是,Realm更改通知。

所以,第一个问题。我应该让我的框架的用户直接初始化对象吗?他们在Realm初始化程序中已经有了这些选项,如果他们选择使用它们,他们将对此负责。但是,我喜欢使用静态方法的工厂模式。像这样:

extension Dog {
public static func retreiveManagedDog() throws -> Dog {
let dog = Dog()
do{
let realm = try Realm()
realm.beginWrite()
realm.add(dog)
try realm.commitWrite()
}catch{
throw error
}
return dog
}
}

对于这个用例来说,这是一个好的设计模式吗?

其次,下一个问题是更新对象。由于所有Realm对象都必须在写入事务中更新,我不希望我的框架的用户为了更改名称而必须编写一堆样板代码。所以,我写这样的函数:

//MARK: Extension that has functions to update properties
extension Dog {
public func updateName(_ name: String?) throws {
do{
let realm = try Realm()
realm.beginWrite()
self.name = name
try realm.commitWrite()
}catch{
throw error
}
}
}

注意,我的对象定义有private(set)正是因为这个原因。它将有助于强制我的框架的用户使用我的setter方法。

总的来说,我试图用这种方式包装Realm是不是疯了?其他持久存在的优秀框架通常封装所有的SQL-Lite/CoreData逻辑。我还想提出一些建议,总体上改进这一模式。

幸运的是,我不认为你的问题有任何硬性的正确答案。这真的取决于你想做什么。

首先,最好不要篡改默认的Realm或默认的Realme配置,因为任何直接使用Realm的应用程序都可能会操纵这两种配置。您还需要确保为模型类型命名名称,并将它们从默认模式中排除。(同样,您可能希望只使用内部定义的模型的模式来打开框架的领域。)

至于你的API,它看起来是什么样子将取决于你想在框架的上下文中使用Realm的目的。

如果Realm是一个实现细节,那么通过上面描述的API来控制用户如何与基于Realm的对象交互是有意义的。这样,您就可以准确地控制用户可以对模型对象执行什么操作,并确保它们不会被修改为状态无效(如果这是一个问题的话)。

例如,您可能希望通过您提供的API为用户处理Realm对象上的注册和取消注册观察者块,该API指定其自身的前提条件和要求。如果观察对象的时间段与框架中的其他对象或系统一致或由其控制,这可能会很有用:而不是告诉用户如何存储他们的通知令牌以及何时处理它们,你可以在幕后处理所有这些细节,并确保用户不会在你的框架中滥用Realm。

你甚至可以将其发挥到极致,通过使你的Realm类型符合某些协议,并让你的API消费和销售该协议类型,让你的用户看不到Realm的使用。这样,你的用户就不会知道你的对象是Realm对象,也不会想把它们粘在自己的Realm中,复制它们,等等。

然而,如果你想让用户知道你在API中为他们提供Realm对象,甚至可能在他们自己使用Realm的同时使用它们(例如,将它们放在他们自己的Realm中),那么明确地将它们作为Realm对象出售是有意义的,可能会使用辅助API,比如你出于方便的原因严格描述的那些API。在这种情况下,你会想一想你的框架对Realm的使用如何避免干扰你的消费者对Realme的使用。

相关内容

  • 没有找到相关文章

最新更新