面向Swift协议的混合范围

时间:2017-07-21 16:54:20

标签: swift scope swift-protocols protocol-extension protocol-oriented

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

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)
    }
}
除了cusotmAction()之外,

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

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

1 个答案:

答案 0 :(得分: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的继承问题。我希望这有帮助!