mercredi 10 août 2022

Elegant solution to initalize a struct with many fields

In my program, I am trying to find an elegant solution to initalize a user struct. The problem I am facing is I have many, many fields which make initalizing the user bulky and messy. There is one thing to note which may be helpful:

  1. When a user is first registered to the app, some fields I want to have default values such as a bio, school, ocupation, etc. (because they have not yet had the chance to populate the data)

I have already tried to wrap other structs around the fields to make the class less messy, but still seems to be a terrible work around.

public struct User {
    
    //MARK: - Fields

    var email: String
    var userSettings: UserSettings
    var userProfile: UserProfile
    var uid: String
    
    
    init?(with userNode: [String: Any]) {
        
        guard let userProfile = UserProfile(userNode: userNode),
              let userSettings = UserSettings(userNode: userNode),
              let email = userNode[EMAIL] as? String,
              let uid = userNode[UID] as? String else { return nil }
        
        self.userProfile = userProfile
        self.userSettings = userSettings
        self.email = email
        self.uid = uid

    }
    
    /**
        Initalize a new user with credentials. Will initalize user with default settings and profile
     */
    init?(with credentials: AuthCredentials,
          profileDownloadUrl: [String],
          uid: String) {
        
        guard let birthday = credentials.birthday,
              let firstName = credentials.firstName,
              let lastName = credentials.lastName,
              let gender = credentials.gender,
              let preference = credentials.preference,
              let geoHash = credentials.location?.geoHash,
              let latitude = credentials.location?.latitude,
              let longitude = credentials.location?.longitude,
              let email = credentials.email else {
            return nil
        }
        
        //Create default profile
        self.userProfile = UserProfile(birthday: birthday,
                                         profilePictures: profileDownloadUrl,
                                         firstName: firstName,
                                         lastName: lastName)
        //Create default settings
        self.userSettings = UserSettings(minSeekingAge: MAX_AGE,
                                         maxSeekingAge: MIN_AGE,
                                         distanceRange: MAX_DISTANCE_RANGE,
                                         gender: gender,
                                         preference: preference,
                                         geoHash: geoHash,
                                         latitude: latitude,
                                         longitude: longitude)
        
        //Assign email
        self.email = email
        
        //Assign user id
        self.uid = uid

    }

}

What is the recomended design pattern to use? I've looked into the builder design pattern, but personally I am not a fan, as I will still have to manually set as many fields.

Aucun commentaire:

Enregistrer un commentaire