$30 off During Our Annual Pro Sale. View Details »

Protocols. What's the Big Deal?

Protocols. What's the Big Deal?

Slides from my Swift London Talk about Protocols in Swift

Abizer Nasir

July 20, 2015
Tweet

More Decks by Abizer Nasir

Other Decks in Programming

Transcript

  1. Protocols:
    What’s the Big Deal?
    Abizer Nasir | @abizern | abizern.org

    View Slide

  2. Protocols
    Are Not New
    To Cocoa

    View Slide

  3. - I conform to a protocol, so I honour this
    interface
    - Apply a common set of behaviours in a single
    inheritance system.
    UITableViewDataSource
    UIApplicationDelegate
    NSFetchedResultsSectionInfo

    View Slide

  4. View Slide

  5. struct Homer {
    ...
    var krusty: Krusty
    }
    Not much good having an embedded Krusty object.

    View Slide

  6. struct Homer {
    ...
    var krusty: KrustyDelegate
    }
    Whenever we want to do something Krusty like - we
    bounce out to the delegate
    But what about the other Franchisees?

    View Slide

  7. We could declare an array of Franchisees
    let franchisees: Array = [“Homer”, “Ned”, “Smithers”]
    But then we have to declare a delegate object for
    each. of them, or use some kind of factory method.

    View Slide

  8. FizzBuzz
    — If the number is a multiple of 3, print “Fizz”
    — If the number is a multiple of 5, print “Buzz”
    — If the number is a multiple of 3 and 5, print
    “FizzBuzz”
    — Otherwise, just print the number

    View Slide

  9. So for something like this:
    [1, 2, 3, 5, 10, 15]
    We get:
    [“1”, “2”, “Buzz”, “Fizz”, “Fizz”, “FizzBuzz”]

    View Slide

  10. Extend Protocol to deal with this
    extension SequenceType where Generator.Element == Int {
    func fizzBuzz() -> [String] {
    return self.map { item -> String in
    switch (item % 3, item % 5) {
    case (0, 0):
    return “FizzBuzz”
    case (0, _):
    return “Buzz”
    case (_, 0):
    return “Fizz”
    default:
    return “\(item)”
    }
    }
    }
    }

    View Slide

  11. Provide configuration
    extension SequenceType where
    Generator.Element == Int {
    func fizzBuzz(options: [(Int, String)]) -> [String] {
    return self.map { item -> String in
    var output = “”
    for (divisor, description) in options {
    if item % divisor == 0 {
    output += description
    }
    }
    guard !output.isEmpty else { return “\(item)” }
    return output
    }
    }
    }

    View Slide

  12. Add a type constraint
    extension SequenceType where
    Generator.Element == Int,
    Generator.Element: CustomStringConvertible {
    func fizzBuzz(options: [(Int, String)]) -> [String] {
    return self.map { item -> String in
    var output = “”
    for (divisor, description) in options {
    if item % divisor == 0 {
    output += description
    }
    }
    guard !output.isEmpty else { return item.description }
    return output
    }
    }
    }

    View Slide

  13. Create a FizzBuzz Protocol
    protocol FizzBuzzable {
    func fizzBuzzValue() -> Int
    }

    View Slide

  14. Create a FizzBuzz Protocol
    protocol FizzBuzzable {
    func fizzBuzzValue() -> Int
    }
    extension Int: FizzBuzzable {
    func fizzBuzzValue() -> Int {
    return self
    }
    }

    View Slide

  15. Change the Type Constraint
    extension SequenceType where
    Generator.Element: FizzBuzzable,
    Generator.Element: CustomStringConvertible {
    func fizzBuzz(options: [(Int, String)]) -> [String] {
    return self.map { item -> String in
    var output = “”
    var value = item.fizzBuzzValue()
    for (divisor, description) in options {
    if value % divisor == 0 {
    output += description
    }
    }
    guard !output.isEmpty else { return value.description }
    return output
    }
    }
    }

    View Slide

  16. This works
    [1, 3, 5, 10, 15].fizzBuzz( [(3, “Fizz”), (5, “Buzz”)] )
    // [“1”, “Fizz”, “Buzz”, “Buzz”, “FizzBuzz”]

    View Slide

  17. Extend other types to implement FizzBuzzable
    struct Shape {
    let sides: Int
    }
    extension Shape: FizzBuzzable {
    func fizzBuzzValue() -> Int {
    return sides
    }
    }
    extension Shape: CustomStringConvertible {
    var description: String {
    return sides.description
    }
    }

    View Slide

  18. And you can fizz buzz that as well
    [Shape(sides: 1), Shape(sides: 3), Shape(sides: 15)].fizzBuzz([(3, “Fizz”), (5, “Buzz”)])
    // [“1”, “Fizz”, “FizzBuzz”]
    The mechanics of doing the actual FizzBuzz has been
    removed from the configuration of the FizzBuzz.

    View Slide

  19. View Slide

  20. data TrafficLight = Red | Yellow | Green deriving (Eq, Ord, Show)
    let r = Red
    let g = Green
    r == g # False
    r < g # True
    r # Red

    View Slide

  21. View Slide

  22. View Slide

  23. https://realm.io/news/altconf-
    airspeed-velocity-bottom-up-
    programming-in-swift/

    View Slide

  24. This is what it’s like to
    read a blog post.

    View Slide

  25. This is what we have to do
    to properly internalise new
    stuff.

    View Slide

  26. Thank You
    Abizer Nasir | @abizern | abizern.org

    View Slide