我对Swift中灵活的通用服务定位器设计模式实现感兴趣。
一种简单的方法可能如下:
// Services declaration
protocol S1 {
func f1() -> String
}
protocol S2 {
func f2() -> String
}
// Service Locator declaration
// Type-safe and completely rigid.
protocol ServiceLocator {
var s1: S1? { get }
var s2: S2? { get }
}
final class NaiveServiceLocator: ServiceLocator {
var s1: S1?
var s2: S2?
}
// Services imlementation
class S1Impl: S1 {
func f1() -> String {
return "S1 OK"
}
}
class S2Impl: S2 {
func f2() -> String {
return "S2 OK"
}
}
// Service Locator initialization
let sl: ServiceLocator = {
let sl = NaiveServiceLocator()
sl.s1 = S1Impl()
sl.s2 = S2Impl()
return sl
}()
// Test run
print(sl.s1?.f1() ?? "S1 NOT FOUND") // S1 OK
print(sl.s2?.f2() ?? "S2 NOT FOUND") // S2 OK
但是如果服务定位器能够处理任何类型的服务而不改变它的代码,那就更好了。在Swift中如何实现这一点?
注意:服务定位器是一个非常有争议的设计模式(有时甚至称为反模式),但是请在这里避免讨论这个主题。
1条答案
按热度按时间o8x7eapl1#
实际上,我们可以利用Swift的类型推理能力来获得一个灵活的通用 * 和类型安全 * 的服务定位器。
然后可按如下方式使用:
这已经是一个可用的实现了,但是它对于允许延迟服务初始化也是有用的。
它可以按以下方式使用:
我认为结合使用服务定位器和依赖注入可以避免前一种模式的一些缺点。