3

我有一个面向协议的编程概念问题。假设我正在创建一个协议 Foo,并且我想在协议扩展中使用函数 action() 来扩展 Foo。action() 将始终基本相同,无论谁在实施,所以我不想重复这段代码。action() 中唯一改变的部分是 prop,prop 需要是实例属性。所以我的符合结构应该只需要定义道具,然后动作就会正常工作。这段代码很好,看起来像这样:

protocol Foo {
    var prop : String {get set}
}
extension Foo {
    func action() -> String {
        return prop + ": Applied Action."
    }
}

但现在问题来了。假设 prop 是我不希望其他类访问的信息。我希望他们只能通过 action() 访问它。在当前的 swift 中,prop 必须至少是内部的,因为协议是内部的,但我需要它是私有的,这样消费类就不会意外修改属性或读取我只希望它们通过 action() 访问的信息. 我可以将 action() 添加到协议中,但是每次结构符合时我都需要重写 action()。

同样的例子也可以扩展到一个函数:

protocol Foo {
     //customization point by conforming class
    func customAction(str: String) -> String
}
extension Foo {
    func action() -> String {
        //Do some default work
        let str = "some string created from previous default work"
        return customAction(str: str)
    }
}

action() 将始终是相同的实现,除了 cusotmAction()。因此,我需要符合标准的类来实现 customAction(),但我不希望任何外部类调用 customAction(),因为它只提供一些只能在 action() 内部使用的特定行为。因此我需要 customAction() 是私有的,但同样,这是不可能的。

所以这是我的问题,这只是面向协议编程的一个细分吗?我如何使用协议来编写这种类型的代码,而不给 prop/customAction() 太多的范围,或者不必一遍又一遍地重写 action() 内部的相同代码?这个例子相当简单,但我面临同样问题的更复杂版本。在 POP 方面是否有不同的方法来看待这个问题,或者我应该寻找一种更面向对象的方法?

4

1 回答 1

0

我不认为这必然是面向协议编程作为一个概念的回退,而仅仅是您使用它的语言。也许 Swift 在设计时并没有考虑到这些情况。但是,我认为解决此问题的一种方法是使用组合,在该组合中您创建一个对象,您希望action在其中定义函数,例如使用无法从外部访问的状态。看看这个例子:

struct Foo {
    init(prop: String) {
        self.prop = prop
    }

    func action() -> String {
        return prop + ": Applied Action."
    }

    private let prop: String
}


class Test {
    let foo = Foo(prop: "TEST")
}

在这种情况下,可以以与使用协议时相同的方式(但不完全相同)Test定义自己的方式。prop话虽如此,您现在可以调用foo实例内部的所有函数,Test而无需访问底层变量。这样做(使用组合)还可以让您远离导致人们首先使用 POP 的继承问题。我希望这有帮助!

于 2017-07-21T18:59:53.297 回答