Подтвердить что ты не робот

Что такое протокол-ориентированное программирование в Swift? Какую добавленную стоимость он приносит?

С сайта Apple: "В основе дизайна Swift лежат две невероятно мощные идеи: протоколно-ориентированное программирование и первоклассная семантика значений".

Может кто-нибудь объяснить, что такое протоколно-ориентированное программирование и какую пользу оно приносит?

Я прочитал это и посмотрел видео по протоколу в Swift, но, исходя из опыта Objective-C, до сих пор не понял этого. Я прошу дать очень простой ответ на английском языке вместе с фрагментами кода и техническими подробностями о том, чем он отличается от Objective-C.

Просто одно из заблуждений, которые у меня возникают, это использование <tableViewDelegate, CustomDelegate> Не могли бы мы также соответствовать нескольким протоколам в Objective-C? Итак, еще раз, как новый Swift?


РЕДАКТИРОВАТЬ: См. Видео -ориентированные просмотры видео. Я считаю, что это видео является более простым и легче понять смысл использования. Само видео WWDC немного продвинуто и требует большей широты. Кроме того, ответы здесь несколько абстрактны.

4b9b3361

Ответ 1

Предисловие: POP и OOP не являются взаимоисключающими. Это парадигмы проектирования, которые очень сильно связаны между собой.

Первичным аспектом POP over OOP является то, что предпочитает композицию по наследованию. Для этого есть несколько преимуществ.

В больших иерархиях наследования классы-предки имеют тенденцию содержать большинство (обобщенных) функциональных возможностей, а листовые подклассы составляют лишь минимальные вклады. Проблема здесь в том, что классы предков в конечном итоге делают много вещей. Например, приводы Car, хранят груз, пассажиры на сиденьях, играют музыку и т.д. Это много функциональных возможностей, которые кажутся разными, но все они неразделимы в классе Car. Потомки Car, такие как Ferrari, Toyota, BMW и т.д., Вносят минимальные изменения в этот базовый класс.

Следствием этого является сокращение использования кода. Мой BoomBox также играет музыку, но это не автомобиль. Наследование функции воспроизведения музыки с Car невозможно.

Вместо этого Swift рекомендует, чтобы эти большие монолитные классы были разбиты на состав меньших компонентов. Эти компоненты могут быть более легко использованы повторно. Оба Car и BoomBox могут использовать MusicPlayer.

Swift предлагает несколько функций для достижения этой цели, но наиболее важными являются расширения протокола. Они позволяют реализовать протокол отдельно от своего класса реализации, поэтому многие классы могут просто реализовать этот протокол и мгновенно получить его функциональные возможности.

Ответ 2

В Objective C протокол - это то же самое, что и интерфейс на большинстве языков. Таким образом, использование Objective C ограничено SOLID принцип "Зависит от абстракций. Не зависит от конкреций".

В протоколах Swift было так серьезно улучшено, что, поскольку они все еще могут использоваться как интерфейсы, на самом деле они ближе к классам (например, Абстрактные классы в С++)

В Objective C единственным способом совместного использования функций между классами является наследование. И вы можете наследовать единственный один родительский класс. В Swift вы также можете принять столько протоколов, сколько хотите. И поскольку протоколы в Swift могут иметь реализацию по умолчанию, они дают нам полнофункциональное Multiple inheritance. Большая гибкость, лучшее повторное использование кода - удивительный!

Вывод:

Протоколированное программирование в основном совпадает с ООП, но оно уделяет дополнительное внимание совместному использованию функций не только через наследование, но и через принятие протокола (Состав над наследованием).

Стоит упомянуть, что в С++ абстрактные классы очень похожи на протоколы в Swift, но никто не говорит, что С++ поддерживает определенный тип OOP. Таким образом, в общем случае POP является одной из версий ООП, если мы говорим о парадигмах программирования. Для Swift POP - улучшенная версия OOP.

Ответ 3

Меня удивило, что ни в одном из ответов не упоминается тип значения в POP.

Чтобы понять, что такое протоколно-ориентированное программирование, вам необходимо понять, каковы недостатки объектно-ориентированного программирования.

  1. У него (Objc) есть только одно наследство. Если у нас очень сложная иерархия наследования, нижний класс может содержать много ненужных состояний.
  2. Он использует класс, который является ссылочным типом. Тип ссылки может привести к небезопасному коду. Например, обработка коллекции ссылочных типов во время их изменения.

В то время как в протокол ориентированного программирования в Swift:

  1. Может соответствовать нескольким протоколам.
  2. Может использоваться не только классом, но и структурами и перечислениями.
  3. Он имеет расширение протокола, которое дает нам общую функциональность для всех типов, которые соответствуют протоколу.
  4. Предпочитает использовать тип значения вместо ссылочного типа. Взгляните на стандартную библиотеку swift здесь, вы можете найти, что большинство типов являются структурами, которые являются типом значения. Но это не значит, что вы вообще не используете класс, в некоторых ситуациях вы должны использовать класс.

Таким образом, протоколно-ориентированное программирование - это не что иное, как очередная парадигма программирования, которая пытается устранить недостатки ООП.

Ответ 4

Добавление к ответу выше

Протокол - это интерфейс, в котором объявляется сигнатура методов и свойств, и любой подкласс, относящийся к классу/структуре/перечислению, должен подчиняться контракту, что означает, что они должны реализовывать все методы и свойства, объявленные в протоколе суперкласса.

Причина использования протокола

Классы обеспечивают одиночное наследование, а структура не поддерживает наследование. Таким образом, протоколы были введены.

Расширение Методы, объявленные внутри протокола, могут быть реализованы внутри расширения, чтобы избежать избыточности кода в случае наследования протокола в нескольких классах/структурах, имеющих одинаковую реализацию методов. Мы можем вызвать метод, просто объявив объект struct/enums. Даже если мы можем ограничить расширение списком классов, только ограниченный класс сможет использовать метод, реализованный внутри расширения, тогда как остальные классы должны реализовывать метод внутри собственного класса.

пример

protocol validator{

    var id : String{ get }
    func capitialise()-> (String)

}

extension validator where Self : test{
    func capitialise() -> String{
        return id.capitalized
    }
}

class test : validator {

    var id: String

    init(name:String) {
        id = name
    }
}

let t = test(name: "Ankit")
t.capitialise()

Когда использовать В ООП предположим, что у нас есть базовый класс транспортного средства, который наследуется самолетом, велосипедом, автомобилем и т.д. Здесь разрыв, ускорение может быть распространенным методом среди трех подклассов, но не летным методом самолета. Таким образом, если мы объявляем flyable метод также в ООП, у подкласса bike и car также есть унаследованный flyable метод, который бесполезен для этого класса. Таким образом, в POP мы можем объявить два протокола: один предназначен для летучих объектов, а другой - для методов разрыва и ускорения. И летный протокол может быть ограничен для использования только самолетом