假设框架通过开放的class A
提供可自定义的服务,该框架公开了共享实例以供使用,如下所示:
open class A {
public static let shared = A()
open func aService() {}
}
该服务的常规用法如下:
A.shared.aService()
重要说明:共享实例本身也可以从class A
代码或框架中的相关代码中使用。
假设您要通过继承自定义服务,但仍然希望按如下所示继续使用共享实例:
override class B: A {
public override func aService() {
super.aService()
}
}
不幸的是,当您引用共享实例时,它引用了class A
实例,而您希望它引用了继承的类实例。
B.shared.aService() // Failed!: This actually calls A.shared.aService()
一种修复方法是使构造如下:
class A {
public static var shared = A()
}
那么您确定在应用内使用该服务之前,请按以下步骤更改实例:
A.shared = B()
B.shared.aService() // OK! This actually calls B.aService()
尽管整个过程都可行,但我想使其自动化,而不是依赖于更改共享实例的初始行。
你会怎么做?
[用于游戏的代码] ,说明了要实现的目标并帮助您更好地理解问题
open class A {
public static var shared = A()
open func aService() {
print("\(type(of: self)): service (from A)")
}
}
class B: A {
public override func aService() {
super.aService()
print("\(type(of: self)): service (from B)")
}
}
A.shared = B() // Question : How to remove the need to this line, yet achieving the same functionality (and output)
A.shared.aService()
B.shared.aService()
// The output (which is correct) :
//B: service (from A)
//B: service (from B)
//B: service (from A)
//B: service (from B)
答案 0 :(得分:1)
有解决方案,但是...
我个人同意这里的其他评论。 真的听起来不像是单例模式的工作。
在当前解决方案中,您似乎很乐意在执行过程中覆盖单例实例,这意味着它不是单例。仅应该有一个单例实例,并且如果您可以不中断任何内容而不断创建新实例并将其分配给shared
变量,那么就没有必要在应用程序中拥有这种全局状态。 / p>
但是,为了记录在案,您可以使用struct
来实现所需的目的,shared
构成每个类的静态实例,并且可以检测调用上下文并返回适当的上下文每次访问protocol ExampleProtocol {
static var shared: ExampleProtocol { get }
func service()
}
struct ExampleProvider {
private static var a = A()
private static var b = B()
static func instance(type: ExampleProtocol.Type) -> ExampleProtocol {
return type == A.self ? ExampleProvider.a : ExampleProvider.b
}
}
class A: ExampleProtocol {
static var shared: ExampleProtocol {
return ExampleProvider.instance(type: Self.self)
}
func service() {
print("Hello")
}
}
class B: A {
override func service() {
print("Goodbye")
}
}
A.shared.service() // Hello
B.shared.service() // Goodbye
时:
{{1}}
是的,您可以实现自己想要的。但是有很充分的理由说你不应该...