繁体   English   中英

Swift中通用类型的工厂(协议和泛型)

[英]Factory of generic types in Swift (Protocols and generics)

我正在尝试创建一个实现协议的泛型类型的工厂。 问题是在适配器工厂的make方法中我得到以下错误: Protocol 'Adapter' can only be used as a generic constraint because it has Self or associated type requirements

这是我现在正在做的一个例子:

protocol Adapter {

    typealias T

    static func method1(parameter: T)
}

final class AdapterFactory<T>: NSObject {

    static func make(name: String = "") -> Adapter.Type {

        switch name {

        case "Adapter1":
            return ConcreteAdapter1<T>.self

        default:
            return ConcreteAdapter2<T>.self
        }

    }
}

final class ConcreteAdapter1<T>: NSObject, Adapter {

    static func method1(parameter: T) {
        // bla, bla, bla
    }
}

您可以使用swift标准库中使用的模式(请参阅Sequence和AnySequence),即使用AnyAdapter来实现Adapter协议,方法是将每个方法调用委托给底层实现(适配器协议的具体实现,如ConcreteAdapter1)或使用闭包。

然后您的工厂将返回AnyAdapter而不是Adapter。 一开始可能看起来不自然,但是使用AnyAdapter作为类型提供了与使用协议相同的优势(显然它是一种解决方法),因为AnyAdapter本身不是具体的实现,而是将实现委托给具体实现。

这是代码

protocol Adapter {

    typealias Element

    func method1(parameter: Element)

    func method2(parameter : Element)
}




struct AnyAdapter<Element> : Adapter {

    private let _method1 : (Element) -> ()

    private let _method2 : (Element) -> ()


    init<A:Adapter where A.Element == Element>(_ base:A) {
        _method1 = { base.method1($0) }
        _method2 = { base.method2($0) }
    }

    func method1(parameter: Element) {
        _method1(parameter)
    }

    func method2(parameter: Element) {
        _method2(parameter)
    }

}



final class ConcreteAdapter1<T>: NSObject, Adapter {

    func method1(parameter: T) {
        print("Concrete Adapter 1 method 1")
    }

    func method2(parameter: T) {
        print("Concrete Adapter 1 method 2")
    }
}



final class ConcreteAdapter2<T> : Adapter {
    func method1(parameter: T) {
        print("Concrete adapter 2 method 1")
    }

    func method2(parameter: T) {
        print("Concrete Adapter 2 method 2")
    }
}

final class AdapterFactory<T>: NSObject {

    static func make(name: String = "") -> AnyAdapter<String> {

        switch name {


        case "Adapter1":
            let concreteAdapter1 = ConcreteAdapter1<String>()
            return AnyAdapter(concreteAdapter1)

        default:
            let concreteAdapter2 = ConcreteAdapter2<String>()
            return AnyAdapter(concreteAdapter2)
        }

    }
}

我没有在协议中使用静态方法来使事情变得更简单,因为静态不适用于泛型类型。

说实话,这是语言的一个缺点,我希望它像java或C#一样简化。

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM