Swift Protocol Oriented Mixed Scope

У меня есть концептуальный вопрос по протоколно-ориентированному программированию. Допустим, я создаю протокол Foo и хочу расширить Foo с помощью функции action() в расширении протокола. action() всегда будет в основном одинаковым, независимо от того, кто его реализует, поэтому я не хочу повторять этот код. Единственная часть action(), которая изменяется, это prop, и prop должна быть свойством экземпляра. Так что моей соответствующей структуре просто нужно определить опору, и тогда действие будет работать правильно. Этот код в порядке и выглядит так:

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

Но теперь здесь есть подвох. Допустим, проп - это информация, к которой я не хочу, чтобы другие классы имели доступ. Я хочу, чтобы они имели к нему доступ только через 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, или я должен смотреть на более объектно-ориентированный подход?

1 ответ

Я не верю, что это обязательно запасной вариант протокольно-ориентированного программирования как концепции, а просто язык, на котором вы его используете. Возможно, 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. Надеюсь, это поможет!

Другие вопросы по тегам