我可以使用一个通用的返回类型,而不必垂头丧气?

时间:2019-01-30 16:37:17

标签: generics design-patterns swift4

我的代码中有2种不同类型的凭据对象。

我想做的是使用一个泛型函数基于Object.TYPE构造并返回正确的对象

所以基本上我想无论基于何种条件改变返回类型和建设。

我的代码似乎是工作,但在我执行我需要使用forced downcast

我还必须为我的2个不同的凭证创建一个"dummy protocol“,这似乎也是“错误的”

这让我怀疑我是用错误的方式做事的。

如何才能做到这一点而无需向下转换?

public protocol C {    
}

//常规创建方法

public enum Credentials {
    case CredentialsIA(apiKey: String, apiSecret: String)
    case CredentialsO(username: String, secret: String, ipsName: String)
    func crendential<T:C>( type: T.Type) -> T {
        switch self {
        case .CredentialsIA(let apiKey, let apiSecret):
            return IACredentials(kAPIKey: apiKey, kAPISecret: apiSecret) as! T
        case .CredentialsO(let username, let secret, let ipsName):
              return OCredential(kUsername: username, kAPIKey: secret, kIPSName: ipsName) as! T
        }
    }
}

凭据类型

public struct IACredentials: C {
    public let kAPIKey: String
    public let kAPISecret: String
    public init(kAPIKey: String, kAPISecret: String) {
        self.kAPIKey = kAPIKey
        self.kAPISecret = kAPISecret
    }
}
public struct OCredential: C {
    public let kUsername: String
    public let kAPIKey: String
    public let kIPSName: String
    public init(kUsername: String, kAPIKey: String, kIPSName: String ) {
        self.kUsername = kUsername
        self.kAPIKey = kAPIKey
        self.kIPSName = kIPSName
    }
}

实例

let credentialsA: Credentials = Credentials.CredentialsIA(apiKey: kAPIKey, apiSecret: kAPISecret)

let credentialsB : Credentials = Credentials.MIPCredentialsOriient(username: "sds", secret: "sdsd", ipsName: "sssd")

初始化后的用法

 let credential:IACredentials = credentialsA.crendential(type: IACredentials.self)

1 个答案:

答案 0 :(得分:0)

如果没有降职,就不能使用您的特定班级。但是还有另一个问题。

您的代码似乎是缺少一些东西的模板方法实现。您的假人interface

我认为,您应该自己问这个问题:CredentialsIAOCredential为何相同,它们的共同点是什么?并在您的界面中使用它。如果可以做到,则可以使用界面执行任务,而无需知道其确切类型。否则,您需要向下转换。

例如:

protocol C{
    func myCommonPointFunc() -> Something
}

class CredentialsIA: C{
    func myCommonPointFunc() -> Something{
        //implementation
    }
}

class OCredential: C{
    func myCommonPointFunc() -> Something{
        //implementation
    } 
}

用法:

let credentialsA: Credentials = Credentials.CredentialsIA(apiKey: kAPIKey, apiSecret: kAPISecret)
var result = creadentailsA.credential().myCommonPoinFunc()

此外,此方法还防止您将类类型传递给enum的{​​{1}}方法。您甚至可以使用实现credential()而不是factory classes

factory interface

也许这个link会有所帮助。