跨继承共享实例

时间:2020-04-20 12:06:00

标签: swift inheritance

假设框架通过开放的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)

1 个答案:

答案 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}}

是的,您可以实现自己想要的。但是有很充分的理由说你不应该...