Isu*_*uru 6 dao data-access-layer realm ios swift
我一直在一些小项目中使用Realm,我非常喜欢它.我希望继续在更大的项目中使用它,我正在寻找更好的结构我的数据访问层.
我遇到了这个类似的问题,并试图建立我在那里找到的信息.在那里讨论的方法是DAO模式,所以我给了它一个镜头.
这是我的模特课.
class Chat: Object {
dynamic var id: String = ""
dynamic var createdAt: Date = Date()
dynamic var creatorId: String = ""
dynamic var title: String?
let chatMessages = List<ChatMessage>()
override static func primaryKey() -> String? {
return "id"
}
convenience init(fromJSON json: JSON) {
self.init()
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个包含ChatDAOProtocol所有方便助手方法.
protocol ChatDAOProtocol {
func addMessage(_ message: ChatMessage)
func getChatThumbnail() -> UIImage
func getParticipants(includingMe: Bool) -> [Participant]?
static func getChat(fromId id: String) -> Chat?
static func getChat(fromCreatorId id: String) -> Chat?
}
Run Code Online (Sandbox Code Playgroud)
最后,我创建了另一个调用ChatHelper所有协议方法的类.
class ChatHelper: ChatDAOProtocol {
func addMessage(_ message: ChatMessage) {
}
func getChatThumbnail() -> UIImage {
return UIImage()
}
func getParticipants(includingMe: Bool) -> [Participant]? {
return nil
}
static func getChat(fromId id: String) -> Chat? {
return nil
}
static func getChat(fromCreatorId id: String) -> Chat? {
return nil
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎比在VC和东西上遍布所有数据库相关代码更好.但我还是有些疑惑.
例如,假设我需要获得聊天的所有参与者,现在我必须在ChatHelper课堂上调用该方法.如果我想简单地获得聊天标题,我会调用对象本身的title属性Chat.看起来不是一个非常统一的界面.我是否应该在帮助程序中包含所有属性的getter和setter.因此Chat永远不会直接调用该对象(除了可能创建实例).
要么
我应该使Chat对象本身符合ChatDAOProtocol协议吗?所以所有便利方法以及属性都可以直接从Chat对象直接访问?
还是有比这两者更好的方法?
这是一个相当棘手的问题,因为它实际上取决于您想要从与 Realm 的直接交互中抽象出多少东西,以及您想要在多大程度上对 Realm 的性能做出妥协。
就我个人而言,我认为如果您抽象出查询和写入逻辑,但仍然直接从 Realm 模型对象中读取,那就没问题了。如果您迁移到另一个基于对象的数据库(如 Core Data),那么虽然您将重构父类,但这些对象属于其他对象(例如,RLMObjectto NSManagedObject),但业务逻辑从这些对象读取的方式不会改变。
但你绝对需要小心的一件事是,以一种非常低效地利用 Realm 的方式抽象逻辑。
我可以看到的主要示例是在您的getParticipants方法中,您返回一个标准 Swift 数组。将 RealmResults对象转换为这样的对象会导致对内存中的每个对象进行分页(而不是根据请求延迟加载),因此您将失去很多 Realm 性能优势。但由于Results对象的行为类似于标准数组,因此如果直接返回对象,则无需更改业务逻辑。
另一个考虑因素:如果您要更新一批对象的单个属性,那么最好确保所有对象都在单个写入事务中更新,而不是每次助手类在内部打开一个写入事务方法被调用。