127
Protocol-Oriented Programming in Swift Oleksandr Stepanov

Protocol-Oriented Programming in Swift

Embed Size (px)

Citation preview

Page 1: Protocol-Oriented Programming in Swift

Protocol-Oriented Programming in Swift

Oleksandr Stepanov

Page 3: Protocol-Oriented Programming in Swift

We are hiring!

Page 4: Protocol-Oriented Programming in Swift

Agenda

Page 5: Protocol-Oriented Programming in Swift

Agenda

• Protocols in Swift vs Objective-C

Page 6: Protocol-Oriented Programming in Swift

Agenda

• Protocols in Swift vs Objective-C

• Protocol-oriented programming

‣ What is that? ‣ Why to use it? ‣ How to use it?

Page 7: Protocol-Oriented Programming in Swift

Agenda

• Protocols in Swift vs Objective-C

• Protocol-oriented programming

‣ What is that? ‣ Why to use it? ‣ How to use it?

• Examples

Page 8: Protocol-Oriented Programming in Swift

Protocols

Page 9: Protocol-Oriented Programming in Swift

protocol someProtocol {

}

Page 10: Protocol-Oriented Programming in Swift

protocol someProtocol { var someInt: Int { get } var someString: String? { get set }}

Page 11: Protocol-Oriented Programming in Swift

protocol someProtocol { var someInt: Int { get } var someString: String? { get set }

func doSomething(inputA: Int) -> String?}

Page 12: Protocol-Oriented Programming in Swift

protocol someProtocol { associatedtype TypeA;

var someInt: Int { get } var someString: String? { get set }

func doSomething(inputA: Int) -> String? func doSomethingWithTypeA(typeA: TypeA)}

Page 13: Protocol-Oriented Programming in Swift

protocol someProtocol { associatedtype TypeA;

var someInt: Int { get } var someString: String? { get set }

func doSomething(inputA: Int) -> String? func doSomethingWithTypeA(typeA: TypeA)}

protocol successorProtocol: someProtocol {

}

Page 14: Protocol-Oriented Programming in Swift

extension somethingProtocol { func doSomethingDifferent() { print("Oh man, that is different") } func doSomethingWithTypeA(typeA: TypeA) { print("typeA: \(typeA)") }}

Page 15: Protocol-Oriented Programming in Swift

ProtocolsSwift Objective-C

Protocol Inheritance ✅ ❌Protocol extensions ✅ ❌

Default implementation ✅ ❌Associated Types (aka Generics) ✅ ❌

Available in structures and enums as well ✅ ❌

Page 16: Protocol-Oriented Programming in Swift

Swift Objective-C

Protocol Inheritance ✅ ❌Protocol extensions ✅ ❌

Default implementation ✅ ❌Associated Types (aka Generics) ✅ ❌

Available in structures and enums as well ✅ ❌

Optional methods ❌ ✅

Protocols

Page 17: Protocol-Oriented Programming in Swift

import Foundation

@objc protocol optionalProtocol {

@objc optional func someOptionalMethod() @objc optional var someOptionalInt: Int { get set }

}

Page 18: Protocol-Oriented Programming in Swift

Swift Objective-C

Protocol Inheritance ✅ ❌Protocol extensions ✅ ❌

Default implementation ✅ ❌Associated Types (aka Generics) ✅ ❌

Available in structures and enums as well ✅ ❌

Optional methods ✅ (@objc) ✅

Protocols

Page 19: Protocol-Oriented Programming in Swift

Protocol-oriented programming

🤔

Page 20: Protocol-Oriented Programming in Swift

Protocol-oriented programming

What is this?

🤔

Page 21: Protocol-Oriented Programming in Swift

WWDC 2015 - Session 408

Protocol-Oriented Programming in Swift

“Swift is a protocol-oriented programming language.”

Dave Abrahams

Page 22: Protocol-Oriented Programming in Swift

WWDC 2015 - Session 408

Protocol-Oriented Programming in Swift

“Swift is a protocol-oriented programming language.”

Dave Abrahams

https://developer.apple.com/videos/play/wwdc2015/408/

https://developer.apple.com/videos/play/wwdc2016/419/

Page 23: Protocol-Oriented Programming in Swift

Cars project 🚗

Page 24: Protocol-Oriented Programming in Swift

Implementation Inheritance approach

Page 25: Protocol-Oriented Programming in Swift

class Car {let wheels = 4

func make() {print("🚗 is built")

} }

Page 26: Protocol-Oriented Programming in Swift

class Car {let wheels = 4

func make() {print("🚗 is built")

} } class CarFactory { var model: Car?

func makeACar() { model?.make() }}

Page 27: Protocol-Oriented Programming in Swift

…class Sedan: Car {}

let sedan = Sedan()

let carFactory = CarFactory()carFactory.model = sedancarFactory.makeACar() // prints “🚗 is built”

Page 28: Protocol-Oriented Programming in Swift

Let’s make 🏎

Page 29: Protocol-Oriented Programming in Swift

…class Bolide: Car {

override func make() { print("🏎 is built")

} }

let bolide = Bolide()let bolideFactory = CarFactory()bolideFactory.model = bolidebolideFactory.makeACar() // prints "🏎 is built" Page 1 of 1

Page 30: Protocol-Oriented Programming in Swift

Let’s make 🏍

Page 31: Protocol-Oriented Programming in Swift

Implementation Inheritance problems

Page 32: Protocol-Oriented Programming in Swift

class CarFactory { var model: Car?

func makeACar() { model?.make() }}

Tight coupling

Hard to maintain

Page 33: Protocol-Oriented Programming in Swift

Inheritance hierarchies

Hard to extend

class Car {let wheels = 4

func make() {print("🚗 is built")

} } class Sedan: Car {}

Page 34: Protocol-Oriented Programming in Swift

Implementation is a white-box

… even using proper encapsulation

class Car {let wheels = 4

func make() {print("🚗 is built")

} } class Sedan: Car {}

Page 35: Protocol-Oriented Programming in Swift

Protocol-oriented programming approach

Page 36: Protocol-Oriented Programming in Swift
Page 37: Protocol-Oriented Programming in Swift

✦ Separation of public interface from the implementation

Page 38: Protocol-Oriented Programming in Swift

✦ Separation of public interface from the implementation

✦ Software defined in components that talk to each other using interfaces

Page 39: Protocol-Oriented Programming in Swift

✦ Separation of public interface from the implementation

✦ Software defined in components that talk to each other using interfaces

✦ May be used in conjunction with classes, structs and enums.

Page 40: Protocol-Oriented Programming in Swift

protocol Vehicle {func make()

}

protocol WheelsVehicle { var wheels: Int { get }}

Page 41: Protocol-Oriented Programming in Swift

…protocol FourWheelsVehicle: WheelsVehicle {}

extension FourWheelsVehicle { var wheels: Int {

get { return 4

} }

}

Page 42: Protocol-Oriented Programming in Swift

…struct Car: Vehicle, FourWheelsVehicle { func make() {

print("🚗 is built") } }

}

struct Bolide: Vehicle, FourWheelsVehicle {func make() {

print("🏎 is built") }

}

Page 43: Protocol-Oriented Programming in Swift

…struct Car: Vehicle, FourWheelsVehicle { func make() {

print("🚗 is built") } }

}

struct Bolide: Vehicle, FourWheelsVehicle {func make() {

print("🏎 is built") }

}

Page 44: Protocol-Oriented Programming in Swift

…struct Car: Vehicle, FourWheelsVehicle { func make() {

print("🚗 is built") } }

}

struct Bolide: Vehicle, FourWheelsVehicle {func make() {

print("🏎 is built") }

}

Page 45: Protocol-Oriented Programming in Swift

…protocol TwoWheelsVehicle: WheelsVehicle {}

extension TwoWheelsVehicle { var wheels: Int { get { return 2 } } }

struct MotorBike: Vehicle, TwoWheelsVehicle { func make() {

print("🏍 is built") } }

}

Page 46: Protocol-Oriented Programming in Swift

…protocol VehicleFactory { var model: Vehicle? { get set }

func makeACar()}

extension VehicleFactory { func makeACar() { model?.make() }}

Page 47: Protocol-Oriented Programming in Swift

…extension VehicleFactory { func repairACar() {

// ... }

}

Page 48: Protocol-Oriented Programming in Swift

…class CarFactory: VehicleFactory { var model: Vehicle?}

let bolide = Bolide()let carFactory = CarFactory()

carFactory.model = bolidecarFactory.makeACar() // prints "🏎 is built"

Page 49: Protocol-Oriented Programming in Swift
Page 50: Protocol-Oriented Programming in Swift

✦ Reusability

Page 51: Protocol-Oriented Programming in Swift

✦ Reusability

✦ Extensibility

Page 52: Protocol-Oriented Programming in Swift

✦ Reusability

✦ Extensibility

✦ Black-boxed

Page 53: Protocol-Oriented Programming in Swift

✦ Reusability

✦ Extensibility

✦ Black-boxed

MORE MAINTAINABLE

Page 54: Protocol-Oriented Programming in Swift

Patterns where it can be useful

Page 55: Protocol-Oriented Programming in Swift
Page 56: Protocol-Oriented Programming in Swift

✦ Data types• Abstraction• Mock objects for test

Page 57: Protocol-Oriented Programming in Swift

✦ Data types• Abstraction• Mock objects for test

✦ Dependency injection

Page 58: Protocol-Oriented Programming in Swift

✦ Data types• Abstraction• Mock objects for test

✦ Dependency injection

✦ Detached architecture• MVVM

Page 59: Protocol-Oriented Programming in Swift

✦ Data types• Abstraction• Mock objects for test

✦ Dependency injection

✦ Detached architecture• MVVM

✦ Testing• Unit• A/B testing interfaces

Page 60: Protocol-Oriented Programming in Swift

Real life example

Page 61: Protocol-Oriented Programming in Swift

Real life exampleUIKit

Page 62: Protocol-Oriented Programming in Swift

Table view cell

Page 63: Protocol-Oriented Programming in Swift

import UIKit struct Event {}

class EventTableViewCell: UITableViewCell {}

Page 64: Protocol-Oriented Programming in Swift

import UIKit struct Event { let icon: UIImage? let title: String let date: Date}

class EventTableViewCell: UITableViewCell { @IBOutlet var iconView: UIImageView! @IBOutlet var titleLabel: UILabel! @IBOutlet var dateLabel: UILabel!}

Page 65: Protocol-Oriented Programming in Swift

import UIKit struct Event { let icon: UIImage? let title: String let date: Date}

class EventTableViewCell: UITableViewCell { @IBOutlet var iconView: UIImageView! @IBOutlet var titleLabel: UILabel! @IBOutlet var dateLabel: UILabel!

func set(event: Event) { iconView.image = event.icon titleLabel.text = event.title dateLabel.text = event.date.description

} }

Page 66: Protocol-Oriented Programming in Swift

Collection view cell

Page 67: Protocol-Oriented Programming in Swift

…class EventTableViewCell: UITableViewCell {

… func set(event: Event) { iconView.image = event.icon titleLabel.text = event.title dateLabel.text = event.date.description

} }

class EventCollectionViewCell: UICollectionViewCell {…

func set(event: Event) { iconView.image = event.icon titleLabel.text = event.title dateLabel.text = event.date.description

} }

Page 68: Protocol-Oriented Programming in Swift

Header view

Page 69: Protocol-Oriented Programming in Swift

…class EventTableViewCell: UITableViewCell { … func set(event: Event) { iconView.image = event.icon titleLabel.text = event.title dateLabel.text = event.date.description

} }class EventCollectionViewCell: UICollectionViewCell {

… func set(event: Event) { iconView.image = event.icon titleLabel.text = event.title dateLabel.text = event.date.description

} }class EventHeaderView: UIView {

… func set(event: Event) { iconView.image = event.icon titleLabel.text = event.title dateLabel.text = event.date.description} }

Page 70: Protocol-Oriented Programming in Swift

Maintenance

Page 71: Protocol-Oriented Programming in Swift

Maintenance

😢

Page 72: Protocol-Oriented Programming in Swift
Page 73: Protocol-Oriented Programming in Swift

POP approach

Page 74: Protocol-Oriented Programming in Swift

protocol EventViewProtocol { var iconView: UIImageView! { get set } var titleLabel: UILabel! { get set } var dateLabel: UILabel! { get set }

func set(event: Event)}

Page 75: Protocol-Oriented Programming in Swift

protocol EventViewProtocol { var iconView: UIImageView! { get set } var titleLabel: UILabel! { get set } var dateLabel: UILabel! { get set }

func set(event: Event)}

extension EventViewProtocol { func set(event: Event) {

iconView.image = event.icontitleLabel.text = event.titledateLabel.text = event.date.description

}}

Page 76: Protocol-Oriented Programming in Swift

…class EventTableViewCell: UITableViewCell { @IBOutlet var iconView: UIImageView! @IBOutlet var titleLabel: UILabel! @IBOutlet var dateLabel: UILabel!}

extension EventTableViewCell: EventViewProtocol{}

Page 77: Protocol-Oriented Programming in Swift

Test it!

🔨

Page 78: Protocol-Oriented Programming in Swift

…import XCTest

class TestView { var iconView: UIImageView! = UIImageView() var titleLabel: UILabel! = UILabel() var dateLabel: UILabel! = UILabel()}

extension TestView: EventViewProtocol {}

Page 79: Protocol-Oriented Programming in Swift

…let eventDate = Date.init()let event = Event.init(icon: UIImage.init(named: “testEventIcon”)

title: "event title", date: eventDate)

let testView = TestView()testView.set(event: event)

Page 80: Protocol-Oriented Programming in Swift

…let eventDate = Date.init()let event = Event.init(icon: UIImage.init(named: “testEventIcon”)

title: "event title", date: eventDate)

let testView = TestView()testView.set(event: event)

XCTAssertEqual ( testView.iconView.image, UIImage.init(named:”testEventIcon”) )

XCTAssertEqual ( testView.titleLabel.text, "event title” )

XCTAssertEqual ( testView.dateLabel.text, eventDate.description )

Page 81: Protocol-Oriented Programming in Swift
Page 82: Protocol-Oriented Programming in Swift

✦ No code duplication -> better maintainable

Page 83: Protocol-Oriented Programming in Swift

✦ No code duplication -> better maintainable

✦ Better testable

Page 84: Protocol-Oriented Programming in Swift

✦ No code duplication -> better maintainable

✦ Better testable

PROFIT!

Page 85: Protocol-Oriented Programming in Swift

One more sample POP + Enums

Page 86: Protocol-Oriented Programming in Swift

One more sample POP + Enums

NSNotification

Page 87: Protocol-Oriented Programming in Swift
Page 88: Protocol-Oriented Programming in Swift

- Literal string names

Page 89: Protocol-Oriented Programming in Swift

- Literal string names

- Potential for mismatched strings

Page 90: Protocol-Oriented Programming in Swift

- Literal string names

- Potential for mismatched strings

- There must be a better approach

Page 91: Protocol-Oriented Programming in Swift
Page 92: Protocol-Oriented Programming in Swift

- Slightly better …

Page 93: Protocol-Oriented Programming in Swift

- Slightly better …

- … but can we do even better?

Page 94: Protocol-Oriented Programming in Swift

}

Page 95: Protocol-Oriented Programming in Swift

}

Page 96: Protocol-Oriented Programming in Swift

}

Page 97: Protocol-Oriented Programming in Swift

How to enhance it with POP ?

}

Page 98: Protocol-Oriented Programming in Swift
Page 99: Protocol-Oriented Programming in Swift
Page 100: Protocol-Oriented Programming in Swift
Page 101: Protocol-Oriented Programming in Swift
Page 102: Protocol-Oriented Programming in Swift
Page 103: Protocol-Oriented Programming in Swift
Page 104: Protocol-Oriented Programming in Swift
Page 105: Protocol-Oriented Programming in Swift
Page 106: Protocol-Oriented Programming in Swift
Page 107: Protocol-Oriented Programming in Swift

Page 108: Protocol-Oriented Programming in Swift
Page 109: Protocol-Oriented Programming in Swift
Page 110: Protocol-Oriented Programming in Swift
Page 111: Protocol-Oriented Programming in Swift

✦ No mismatched strings

Page 112: Protocol-Oriented Programming in Swift

✦ No mismatched strings

✦Simpler to read and maintain

Page 113: Protocol-Oriented Programming in Swift

✦ No mismatched strings

✦Simpler to read and maintain

✦ Notification handlers may be classes, structs and enums

Page 114: Protocol-Oriented Programming in Swift

✦ No mismatched strings

✦Simpler to read and maintain

✦ Notification handlers may be classes, structs and enums

✦ … the same for notification type

Page 115: Protocol-Oriented Programming in Swift
Page 116: Protocol-Oriented Programming in Swift

reusability

Page 117: Protocol-Oriented Programming in Swift

reusability

extensibility

Page 118: Protocol-Oriented Programming in Swift

understandabilityreusability

extensibility

Page 119: Protocol-Oriented Programming in Swift

maintainability

understandabilityreusability

extensibility

Page 120: Protocol-Oriented Programming in Swift

maintainability

understandability

testability

reusability

extensibility

Page 121: Protocol-Oriented Programming in Swift

POP

maintainability

understandability

testability

reusability

extensibility

Page 122: Protocol-Oriented Programming in Swift
Page 123: Protocol-Oriented Programming in Swift

it’s not a

Page 124: Protocol-Oriented Programming in Swift

it’s not a

Page 125: Protocol-Oriented Programming in Swift

treat it carefully

Page 126: Protocol-Oriented Programming in Swift

Thank you!

Page 127: Protocol-Oriented Programming in Swift

Q&A