Swift - Как использовать совершенно разные типы объектов с помощью общих и уникальных методов и поддерживать их масштабируемость - PullRequest
1 голос
/ 22 мая 2019

В проекте, над которым я сейчас работаю, есть два типа пользователей:

  • RegularUser
  • SuperUser

Сетевой уровень APIбыл автоматически сгенерирован с использованием Swagger (по требованию клиента - они не хотят, чтобы я писал свой собственный, к сожалению).

Swagger содержит три класса:

  • SwaggerGlobalAPI(Глобальные методы API)
  • SwaggerRegularUserAPI (методы API, специфичные для RegularUser пользователей)
  • SwaggerSuperUserAPI (методы API, специфичные для SuperUser пользователей)

Проблема заключается в том, что оба класса Swagger API RegularUserAPI и SuperUserAPI содержат сигнатуры общих методов, а также другие сигнатуры не общих методов, уникальные для их собственных.

Пример:

class SwaggerRegularUserAPI {
   func login() {}
   func verifySMSCode() { }
   func getMyStuff() -> Stuff {}
}

class SwaggerSuperUserAPI {
   func login() {}
   func verifySMSCode() {}
   func getMySuperStuff() -> SuperStuff {}
}

После первоначального входа в систему сервер возвращает enum точно, с каким типом пользователя это, и мне нужно решить, использовать ли RegularUserAPI или SuperUserAPI во всем приложении.

Протоколы дают хороший ответ для общих методов, но не очень хороши, когда два класса неесть такие же сигнатуры методов, как getMyStuff() -> Stuff и getMySuperStuff() -> SuperStuff

class SwaggerGlobalAPI {
    func someGlobalMethod()
}

protocol SwaggerUserAPI {
    func login()
    func verifySMSCode()
}

class SwaggerRegularUserAPI: SwaggerUserAPI {
    func login() {}
    func verifySMSCode() {}
    func getMyStuff() -> Stuff {}
}

class SwaggerSuperUserAPI: SwaggerUserAPI {
    func login() {}
    func verifySMSCode() {}
    func getMySuperStuff() -> SuperStuff {}
}

class APIFactory {
    let globalAPI: SwaggerGlobalAPI
    let userAPI: SwaggerUserAPI

    init() {
        globalAPI = SwaggerGlobalAPI()

        switch CurrentUser.type {
        case .regular:
            userAPI = SwaggerRegularUserAPI()
        case .super:
            userAPI = SwaggerSuperUserAPI()
        }
    }
}

class UserStuffViewController: UIViewController {
    let api: APIFactory

    init(api: APIFactory) {
        self.api = api
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fatalError()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        if let userAPI = api as? SwaggerRegularUserAPI {
            let stuff = userAPI.getMyStuff()
        } else if let userAPI = api as? SwaggerSuperUserAPI {
            let stuff = userAPI.getMySuperStuff()
        }
    }
}

Так что теперь, когда вы поймете, как ужасная и очень глупая ситуация, как бы вы предложили мне написатьон достаточно масштабируемый, чтобы я всегда мог добавлять новых типов пользователей с различными классами Swagger API, которые могут иметь некоторые свои уникальные методы?Кроме того, если вы поможете мне улучшить эту архитектуру, это будет благословением!

Большое спасибо:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...