How to use Protocols in Swift (and How Not To)... Part 1
(This is the first in a multi-part series. The subsequent parts will address the comments and questions left on the first part.)
The most influential WWDC talk ever was Dave Abrahams' 2015 talk, Protocol-Oriented Programming in Swift.
Swift had only been out for a year, during which most of us had done little more than dabble until we became confused by nested optionals and string indices.
So by the time WWDC '15 rolled around, the entire Apple developer community was super hungry for any and all pearls of wisdom related to Swift, any magic bullet for it to finally make sense.
Dave Abrahams was throwing a lit Zippo into a swimming pool of gasoline when he:
- Told us his story about an old developer named "Crusty" who convinced him that Swift was all about using protocols instead of classes
- Said, "We have a saying in Swift: don't start with a class, start with a protocol"
- Opined, "At its heart, Swift is protocol-oriented."
- Instructed, "Don't start with a class, start with a protocol."
- Showed an example using structs and protocols (with downloadable playground).
- Recommended that we attend the talk, "Building Better Apps with Value Types in Swift"
- Showed a slide that said, "Protocols and Generics for Testability: So much better than mocks"
People came away from this talk with the following mantra: "Protocols and structs. Protocols and structs."
Meanwhile, who remembers the following statements of Dave's:
- "Once you add a Self-requirement to a protocol, it moves the protocol into a very different world, where the capabilities have a lot less overlap with classes. It stops being usable as a type. Collections become homogenous instead of heterogenous. An interaction between instances no longer implies an interaction between all model types."
- "We trade dynamic polymophism for static polymorphism, but, in return for that extra type information we're giving the compiler, it's more optimizable. So, two worlds."
Pop quiz: in 2015, did you think the "two worlds" were:
(A) OOP, and Protocol-Oriented Programming
(B) Swift protocols, and other Swift protocols
(C) Objective C protocols, and Swift protocols
(D) Using protocols in production code, and using protocols in test code
(E) Protocol extensions that constrain Self to another protocol, and protocol extensions that add protocol conformances directly to types.
(F) C & A
(G) D & E
(H) C & E
Please leave your response in the comments, and be honest about what you thought at that time. (I will discuss the answers in the next post.)
As well, I would like to get the following information from other devs. Copy and paste the following into the comments & answer whichever ones you can. Exact answers are preferred but a general estimate is also fine.
- How common is it in your codebase to use protocols specifically for mocking?
- Besides AppDelegate, how many types in your codebase conform to more than one protocol?
- How many protocols in your codebase are conformed to by more than one type (not including tests)?
- How many different custom type-erasure schemes are implemented in your codebase for some of your own types?
- How many classes/structs exist in your codebase whose ends in "Impl", where the rest of the name is the name of a protocol that type conforms to?
Clap to support the author, help others find it, and make your opinion count.