调用与数据库交互的方法的最佳位置在哪里?

时间:2019-06-22 17:14:09

标签: swift firebase model-view-controller design-patterns architecture

我正在创建一个与Firestore数据库交互的应用程序。到目前为止,我有一个单例类DatabaseManager,其中包含与Firestore数据库有关的所有方法(即get / post方法)。

我有一个名为User的用户模型,该模型具有nameemailphotoURL之类的属性以及某些特定于应用程序的属性。任何用户都可以编辑其个人资料来更新名为EditProfileViewController的视图控制器中的信息。

现在我的问题是:最好是从DatabaseManager.shared.updateInfo(forUser: user)user或某些名称中调用User(其中EditProfileViewControllerUser实例)其他地方?

很抱歉,如果这是一个显而易见的问题,但是在应用程序中会有很多要点,我需要类似的逻辑,所以我想知道什么是最好的设计。此外,我敢肯定,与Firebase / Swift相比,MVC的问题更多。

2 个答案:

答案 0 :(得分:1)

一些想法:

  1. 我可能不是拥有DatabaseManager.shared.update(for:)直接访问单例的功能,而是拥有数据库管理器的属性,使用DatabaseManager.shared进行初始化/注入,并具有与之交互的任何需求数据库使用该引用,例如dataManager.update(for:)。目的是允许您的单元测试在必要时模拟数据库管理器。

  2. 我不会倾向于让视图控制器直接与DatabaseManager进行交互。我们中的许多人都将视图控制器直接与UIKit / AppKit对象进行交互,将其作为MVC / MVP / MVVM /更广泛的“ V”的一部分。我们通常会从视图控制器中解脱出业务逻辑(包括与数据库管理器的交互)。

    我个人也不会将其埋在User对象下。我将其放在数据库管理器的扩展程序中,并从视图模型,演示者或您个人希望使用业务逻辑调用该对象的任何对象中调用。

答案 1 :(得分:0)

您是否有理由使用单例来包含所有Firestore逻辑?用户模型应包含方法updateInfo。

这是我在Firestore中使用的示例:

class Group {

    // can read the var anywhere, but an only set value in this class
    private(set) var groupName: String!
    private(set) var guestsInGroup: Int!
    private(set) var joinedGroup: Bool!
    private(set) var timeStampGroupCreated: Date!
    private(set) var documentId: String!

    init(groupName: String, guestsInGroup: Int, joinedGroup: Bool, timeStampGroupCreated: Date, documentId: String) {
        self.groupName = groupName
        self.guestsInGroup = guestsInGroup
        self.joinedGroup = joinedGroup
        self.timeStampGroupCreated = timeStampGroupCreated
        self.documentId = documentId
    }


    // method to parse Firestore data to array, that table view will display
    class func parseData(snapshot: QuerySnapshot?) -> [Group]{
        var groups = [Group]()

        guard let snap = snapshot else { return groups }
        for document in snap.documents {
            let data = document.data()
            let groupName = data[GROUP_NAME] as? String ?? "No Group Name"
            let guestsInGroup = data[GUESTS_IN_GROUP] as? Int ?? 0
            let joinedGroup = data[JOINED_GROUP] as? Bool ?? false
            let timeStampGroupCreated = data[TIMESTAMP_GROUP_CREATED] as? Date ?? Date()
            let documentId = document.documentID

            // add objects with fetched data into thoughts array
            let newGroup = Group(groupName: groupName, guestsInGroup: guestsInGroup, joinedGroup: joinedGroup, timeStampGroupCreated: timeStampGroupCreated, documentId: documentId)

            groups.append(newGroup)
        }
        return groups
    }
}