SlideShare ist ein Scribd-Unternehmen logo
1 von 92
1
2
Protocol-oriented programming in Swift
Rostyslav Kobyzskyi
Software Engineer
16th Nov, 2016
3
1. Classes and problems
2. Start with Protocol
3. Using Protocols
4. Examples
5. Questions
Agenda
Dave Abrahams
• David Abrahams is a computer
programmer and author
• Abrahams became a member of
the C++ Standards Committee
in 1996
• In 2013 Abrahams became an
employee at Apple Inc, where
he is involved in the
development of the Swift
programming language
Why Protocols?
Classes
• Encapsulation
• Access Control
• Abstraction
• Namespace
• Expressive Syntax
• Extensibility
Classes
• Encapsulation
• Access Control
• Abstraction
• Namespace
• Expressive Syntax
• Extensibility
1. Implicit Sharing
A
B
Data
1. Implicit Sharing
A
B
Data
1. Implicit Sharing
A
B
Data
1. Implicit Sharing
A
B
Data
1. Implicit Sharing
A
B
Ponies
1. Implicit Sharing
B
Ponies
1. Implicit Sharing
B
Ponies
$@#$%?
1. Implicit Sharing
• Defensive Copy
• Inefficiency
• Race Condition
• Locks
• More Inefficiency
• Deadlock
• Complexity
• Bugs!
Values don’t Share.
That’s a good thing
Classes? They overshare…
2. Inheritance
Subclass
Stored
Properties
Superclass
2. Inheritance
One superclass
Subclass
Stored
Properties
Superclass
Instance
2. Inheritance
One superclass
Single Inheritance
Subclass
Stored
Properties
Superclass
Instance
2. Inheritance
One superclass
Single Inheritance
Super class may have Stored Properties
Subclass
Stored
Properties
Superclass
Stored
Properties
Instance
2. Inheritance
One superclass
Single Inheritance
Super class may have Stored Properties
• You must accept them
Subclass
Stored
Properties
Superclass
Stored
Properties
2. Inheritance
One superclass
Single Inheritance
Super class may have Stored Properties
• You must accept them
• Initialization problem
Instance
Subclass
Stored
Properties
Superclass
Stored
Properties
2. Inheritance
One superclass
Single Inheritance
Super class may have Stored Properties
• You must accept them
• Initialization problem
• Don’t break superclass invariants!
Instance
Subclass
Stored
Properties
Superclass
Stored
Properties
2. Inheritance
One superclass
Single Inheritance
Super class may have Stored Properties
• You must accept them
• Initialization problem
• Don’t break superclass invariants!
Know what/how to override (and when not)
Instance
Subclass
Stored
Properties
Superclass
Stored
Properties
3. Lost Type Relationships
class Ordered {
func precedes(other: Ordered) -> Bool
}
func binarySearch(sortedKeys: [Ordered], forKey k: Ordered) -> Int {
var lo = 0, hi = sortedKeys.count
while hi > lo {
let mid = lo + (hi - lo) / 2
if sortedKeys[mid].precedes(k) { lo = mid + 1 }
else { hi = mid }
}
return lo
}
3. Lost Type Relationships
class Ordered {
func precedes(other: Ordered) -> Bool { }
}
3. Lost Type Relationships
class Ordered {
func precedes(other: Ordered) -> Bool
}
{ fatalError(“implement me!”) }
3. Lost Type Relationships
class Ordered {
func precedes(other: Ordered) -> Bool
}
{ fatalError(“implement me!”) } X
3. Lost Type Relationships
class Ordered {
func precedes(other: Ordered) -> Bool
}
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < other.value
}
}
{ fatalError(“implement me!”) } X
class Ordered {
func precedes(other: Ordered) -> Bool
}
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < other.value
}
}
3. Lost Type Relationships
{ fatalError(“implement me!”) } X
class Ordered {
func precedes(other: Ordered) -> Bool
}
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < other.value
}
}
3. Lost Type Relationships
{ fatalError(“implement me!”) } X
class Ordered {
func precedes(other: Ordered) -> Bool
}
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < other.value
}
}
3. Lost Type Relationships
{ fatalError(“implement me!”) } X
`Ordered` does not have a member named `value`
`Ordered` does not have a member named `value`
3. Lost Type Relationships
{ fatalError(“implement me!”) } X
class Ordered {
func precedes(other: Ordered) -> Bool
}
class Label: Ordered { var text: String = “” ... }
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < other.value
}
}
class Ordered {
func precedes(other: Ordered) -> Bool
}
class Label: Ordered { var text: String = “” ... }
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < (other as! Number).value
}
}
3. Lost Type Relationships
{ fatalError(“implement me!”) } X
A better Abstraction
Mechanism
• Support value types (and classes)
• Support static type relationships (and dynamic dispatch)
• Non-monolithic
• Doesn’t impose instance data on models
• Doesn’t impose initialization burdens on models
• Makes clear what to implement
Swift is Protocol-Oriented
Programming Language
Start with a Protocol
Starting override with Protocols
class Ordered {
func precedes(other: Ordered) -> Bool
}
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < other.value
}
}
{ fatalError(“implement me!”) } X
Starting override with Protocols
class Ordered {
func precedes(other: Ordered) -> Bool
}
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < (other as! Number).value
}
}
{ fatalError(“implement me!”) } X
Starting override with Protocols
protocol Ordered {
func precedes(other: Ordered) -> Bool
}
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < (other as! Number).value
}
}
{ fatalError(“implement me!”) } X
Starting override with Protocols
protocol Ordered {
func precedes(other: Ordered) -> Bool
}
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < (other as! Number).value
}
}
{ fatalError(“implement me!”) }
Protocol methods may not have bodies
Starting override with Protocols
protocol Ordered {
func precedes(other: Ordered) -> Bool
}
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < (other as! Number).value
}
}
Method does not override any method
from superclass
Starting override with Protocols
protocol Ordered {
func precedes(other: Ordered) -> Bool
}
class Number: Ordered {
var value: Double = 0
override fund precedes(other: Ordered) -> Bool {
return value < (other as! Number).value}
}
Starting override with Protocols
protocol Ordered {
func precedes(other: Ordered) -> Bool
}
struct Number: Ordered {
var value: Double = 0
fund precedes(other: Ordered) -> Bool {
return value < (other as! Number).value
}
}
Starting override with Protocols
protocol Ordered {
func precedes(other: Ordered) -> Bool
}
struct Number: Ordered {
var value: Double = 0
fund precedes(other: Ordered) -> Bool {
return value < (other as! Number).value
}
}
Starting override with Protocols
protocol Ordered {
func precedes(other: Ordered) -> Bool
}
struct Number: Ordered {
var value: Double = 0
fund precedes(other: Number) -> Bool {
return value < other.value
}
}
Starting override with Protocols
protocol Ordered {
func precedes(other: Ordered) -> Bool
}
struct Number: Ordered {
var value: Double = 0
fund precedes(other: Number) -> Bool {
return value < other.value
}
}
Protocol requires function ‘precedes’ with type ‘(Oredered)’ -> Bool
candidate has non-matching type (`Number`) -> Bool
Starting override with Protocols
protocol Ordered {
func precedes(other: Self) -> Bool
}
struct Number: Ordered {
var value: Double = 0
fund precedes(other: Number) -> Bool {
return value < other.value
}
}
Self requirement
Using out Protocol
func binarySearch(sortedKeys: [Ordered], forKey k: Ordered) -> Int {
var lo = 0, hi = sortedKeys.count
while hi > lo {
let mid = lo + (hi - lo) / 2
if sortedKeys[mid].precedes(k) { lo = mid + 1 }
else { hi = mid }
}
return lo
}
Using out Protocol
func binarySearch(sortedKeys: [Ordered], forKey k: Ordered) -> Int {
var lo = 0, hi = sortedKeys.count
while hi > lo {
let mid = lo + (hi - lo) / 2
if sortedKeys[mid].precedes(k) { lo = mid + 1 }
else { hi = mid }
}
return lo
}
Protocol ‘Ordered’ can only be used as a generic constraint
because if has Self or associated type requirements
Using out Protocol
func binarySearch(sortedKeys: [Ordered], forKey k: Ordered) -> Int {
var lo = 0, hi = sortedKeys.count
while hi > lo {
let mid = lo + (hi - lo) / 2
if sortedKeys[mid].precedes(k) { lo = mid + 1 }
else { hi = mid }
}
return lo
}
Protocol ‘Ordered’ can only be used as a generic constraint
because if has Self or associated type requirements
Using out Protocol
func binarySearch<T: Ordered>(sortedKeys: [T], forKey k: T) -> Int {
var lo = 0, hi = sortedKeys.count
while hi > lo {
let mid = lo + (hi - lo) / 2
if sortedKeys[mid].precedes(k) { lo = mid + 1 }
else { hi = mid }
}
return lo
}
Two-world of Protocols
Without Self Requirement With Self Requirement
func precedes(other: Ordered) -> Bool func precedes(other: Self) -> Bool
Two-world of Protocols
Without Self Requirement With Self Requirement
func precedes(other: Ordered) -> Bool
Usable as a type
sort(inout a: [Ordered])
func precedes(other: Self) -> Bool
Only usable as a generic constraint
sort<T: Ordered>(inout a: [T])
Two-world of Protocols
Without Self Requirement With Self Requirement
func precedes(other: Ordered) -> Bool
Usable as a type
sort(inout a: [Ordered])
Every model must deal with all others
func precedes(other: Self) -> Bool
Only usable as a generic constraint
sort<T: Ordered>(inout a: [T])
Models are free from interaction
Two-world of Protocols
Without Self Requirement With Self Requirement
func precedes(other: Ordered) -> Bool
Usable as a type
sort(inout a: [Ordered])
Every model must deal with all others
Dynamic dispatch
func precedes(other: Self) -> Bool
Only usable as a generic constraint
sort<T: Ordered>(inout a: [T])
Models are free from interaction
Static dispatch
Two-world of Protocols
Without Self Requirement With Self Requirement
func precedes(other: Ordered) -> Bool
Usable as a type
sort(inout a: [Ordered])
Every model must deal with all others
Dynamic dispatch
Less optimizable
func precedes(other: Self) -> Bool
Only usable as a generic constraint
sort<T: Ordered>(inout a: [T])
Models are free from interaction
Static dispatch
More optimizable
A Primitive “Render”
struct Renderer {
func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) }
func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) }
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat) {
print(“arcAt((center), radius: (radius)),” +
+ “ startAngle: (startAngle), endAngle: (endAngle)”)
}
}
Drawable
protocol Drawable {
func draw(randerer: Renderer)
}
Polygon
protocol Drawable {
func draw(randerer: Renderer)
}
struct Polygon: Drawable {
func draw(renderer: Renderer) {
renderer.moveTo(corners.last!)
for p in corners {
renderer.lineTo(p)
}
}
var corners: [CGPoint] = []
}
Circle
protocol Drawable {
func draw(randerer: Renderer)
}
struct Circle: Drawable {
func draw(renderer: Renderer) {
renderer.artAt(center, radius: radius,
startAngle: 0.0, endAngle: twoPi)
}
}
var center: CGPoint
var radius: CGFloat
}
Diagram
protocol Drawable {
func draw(randerer: Renderer)
}
struct Diagram: Drawable {
func draw(renderer: Renderer) {
for f in elements {
f.draw(renderer)
}
}
var elements: [Drawable] = []
}
Test It!
var circle = Circle(
center: CGPoint(x: 187.5, y: 333.5),
radius: 93.75
)
Test It!
var circle = Circle(
center: CGPoint(x: 187.5, y: 333.5),
radius: 93.75
)
var triangle = Polygon(corners: [
CGPoint(x: 187.5, y: 427.25),
CGPoint(x: 268.69, y: 286.625),
CGPoint(x: 106.31, y: 286.625)
])
Test It!
var circle = Circle(
center: CGPoint(x: 187.5, y: 333.5),
radius: 93.75
)
var triangle = Polygon(corners: [
CGPoint(x: 187.5, y: 427.25),
CGPoint(x: 268.69, y: 286.625),
CGPoint(x: 106.31, y: 286.625)
])
var diagram = Diagram(elements: [circle: triangle])
Test It!
var circle = Circle(
center: CGPoint(x: 187.5, y: 333.5),
radius: 93.75
)
var triangle = Polygon(corners: [
CGPoint(x: 187.5, y: 427.25),
CGPoint(x: 268.69, y: 286.625),
CGPoint(x: 106.31, y: 286.625)
])
var diagram = Diagram(elements: [circle: triangle])
diagram.draw(Renderer())
Renderer as Protocol
struct Renderer {
func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) }
func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) }
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat) {
print(“arcAt((center), radius: (radius)),” +
+ “ startAngle: (startAngle), endAngle: (endAngle)”)
}
}
struct Renderer {
func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) }
func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) }
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat) {
print(“arcAt((center), radius: (radius)),” +
+ “ startAngle: (startAngle), endAngle: (endAngle)”)
}
}
Renderer as Protocol
protocol Renderer {
func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) }
func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) }
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat) {
print(“arcAt((center), radius: (radius)),” +
+ “ startAngle: (startAngle), endAngle: (endAngle)”)
}
}
struct Renderer {
func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) }
func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) }
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat) {
print(“arcAt((center), radius: (radius)),” +
+ “ startAngle: (startAngle), endAngle: (endAngle)”)
}
}
Renderer as Protocol
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat)
}
struct Renderer {
func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) }
func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) }
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat) {
print(“arcAt((center), radius: (radius)),” +
+ “ startAngle: (startAngle), endAngle: (endAngle)”)
}
}
Renderer as Protocol
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat)
}
struct Renderer {
func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) }
func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) }
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat) {
print(“arcAt((center), radius: (radius)),” +
+ “ startAngle: (startAngle), endAngle: (endAngle)”)
}
}
Renderer as Protocol
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat)
}
struct TestRenderer: Renderer {
func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) }
func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) }
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat) {
print(“arcAt((center), radius: (radius)),” +
+ “ startAngle: (startAngle), endAngle: (endAngle)”)
}
}
Rendering with CoreGraphics
Retroactive modeling
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat)
}
Rendering with CoreGraphics
Retroactive modeling
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat)
}
Rendering with CoreGraphics
Retroactive modeling
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat)
}
extension CGContext: Renderer {
func moveTo(p: CGPoint) { }
func lineTo(p: CGPoint) { }
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat) { }
}
Rendering with CoreGraphics
Retroactive modeling
extension CGContext: Renderer {
func moveTo(p: CGPoint) {
CGContextMoveToPoint(self, p.x, p.y)
}
func lineTo(p: CGPoint) {
CGContextAddLineToPoint(self, p.x, p.y)
}
func arcAt(center: CGPoint, radius: CGFloat,
startAngler: CGFloat, endAngle: CGFloat) {
let arc = CGPathCreateMutable()
CGPathAddArc(arc, nil, center.x, center.y, radius,
startAngle, endAngle, true)
CGContextAddPath(self, arc)
}
}
Protocols and Generics for Testability
So much better than mocks
struct Bubble: Drawable {
func draw(r: Renderer) {
r.arcAt(center, radius, startAngle: 0, endAngle: twoPi)
r.arcAt(highlightCenter, radius: highlightRadius,
startAngle: 0, endAngle: twoPi
)
}
}
Protocols and Generics for Testability
So much better than mocks
struct Bubble: Drawable {
func draw(r: Renderer) {
r.arcAt(center, radius, startAngle: 0, endAngle: twoPi)
r.arcAt(highlightCenter, radius: highlightRadius,
startAngle: 0, endAngle: twoPi
)
}
}
struct Circle: Drawable {
func draw(r: Renderer) {
r.arcAt(center, radius, startAngle: 0, endAngle: twoPi)
}
}
Protocols and Generics for Testability
So much better than mocks
struct Bubble: Drawable {
func draw(r: Renderer) {
r.circleAt(center, radius)
r.arcAt(highlightCenter, radius: highlightRadius)
}
}
struct Circle: Drawable {
func draw(r: Renderer) {
r.circleAt(center, radius)
}
}
Adding a Circle Primitive
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func arcAt(
center: CGPoint, radius: CGFloat,
startAngle: CGFloat, endAngle: CGFloat)
)
}
Adding a Circle Primitive
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func arcAt(
center: CGPoint, radius: CGFloat,
startAngle: CGFloat, endAngle: CGFloat)
)
}
Adding a Circle Primitive
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func circleAt(center: CGPoint, radius: CGFloat)
func arcAt(
center: CGPoint, radius: CGFloat,
startAngle: CGFloat, endAngle: CGFloat)
)
}
Adding a Circle Primitive
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func circleAt(center: CGPoint, radius: CGFloat)
func arcAt(
center: CGPoint, radius: CGFloat,
startAngle: CGFloat, endAngle: CGFloat)
)
}
New requirement
Adding a Circle Primitive
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func circleAt(center: CGPoint, radius: CGFloat)
func arcAt(
center: CGPoint, radius: CGFloat,
startAngle: CGFloat, endAngle: CGFloat)
)
}
extension TestRenderer {
func circleAt(center: CGPoint, radius: CGFloat) {
arcAt(center, radius: radius, startAngle: 0, endAngle: twoPi)
}
}
Adding a Circle Primitive
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func circleAt(center: CGPoint, radius: CGFloat)
func arcAt(
center: CGPoint, radius: CGFloat,
startAngle: CGFloat, endAngle: CGFloat)
)
}
extension CGContext {
func circleAt(center: CGPoint, radius: CGFloat) {
arcAt(center, radius: radius, startAngle: 0, endAngle: twoPi)
}
}
Protocol Extension
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func circleAt(center: CGPoint, radius: CGFloat)
func arcAt(
center: CGPoint, radius: CGFloat,
startAngle: CGFloat, endAngle: CGFloat)
)
}
extension Renderer {
func circleAt(center: CGPoint, radius: CGFloat) {
arcAt(center, radius: radius, startAngle: 0, endAngle: twoPi)
}
}
New!
Protocol Extension
protocol Renderer {
func moveTo(p: CGPoint)
func lineTo(p: CGPoint)
func circleAt(center: CGPoint, radius: CGFloat)
func arcAt(
center: CGPoint, radius: CGFloat,
startAngle: CGFloat, endAngle: CGFloat)
)
}
extension Renderer {
func circleAt(center: CGPoint, radius: CGFloat) {
arcAt(center, radius: radius, startAngle: 0, endAngle: twoPi)
}
}
Shared Implementation
Protocol Extension
extension Renderer {
func circleAt(center: CGPoint, radius: CGFloat) { ... }
func rectagleAt(edges: CGRect) { ... }
}
extension TestRenderer: Renderer {
func circleAt(center: CGPoint, radius: CGFloat) { ... }
func rectagleAt(edges: CGRect) { ... }
}
Protocol Extension
extension Renderer {
func circleAt(center: CGPoint, radius: CGFloat) { ... }
func rectagleAt(edges: CGRect) { ... }
}
extension TestRenderer: Renderer {
func circleAt(center: CGPoint, radius: CGFloat) { ... }
func rectagleAt(edges: CGRect) { ... }
}
let r = TestRenderer()
r.circleAt(origin, radius: 1)
r.rectangleAt(edges)
Protocol Extension
extension Renderer {
func circleAt(center: CGPoint, radius: CGFloat) { ... }
func rectagleAt(edges: CGRect) { ... }
}
extension TestRenderer: Renderer {
func circleAt(center: CGPoint, radius: CGFloat) { ... }
func rectagleAt(edges: CGRect) { ... }
}
let r = TestRenderer()
r.circleAt(origin, radius: 1)
r.rectangleAt(edges)
Protocol Extension
customization point
extension Renderer {
func circleAt(center: CGPoint, radius: CGFloat) { ... }
func rectagleAt(edges: CGRect) { ... }
}
extension TestRenderer: Renderer {
func circleAt(center: CGPoint, radius: CGFloat) { ... }
func rectagleAt(edges: CGRect) { ... }
}
let r: Renderer = TestRenderer()
r.circleAt(origin, radius: 1)
r.rectangleAt(edges)
91
Questions
92
Thank you
Rostyslav
Software Engineer
rostyslav.kobyzskyi@globallogic.com
+38-093-254-3392

Weitere ähnliche Inhalte

Was ist angesagt?

High Wizardry in the Land of Scala
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scaladjspiewak
 
Introduction to the basics of Python programming (part 3)
Introduction to the basics of Python programming (part 3)Introduction to the basics of Python programming (part 3)
Introduction to the basics of Python programming (part 3)Pedro Rodrigues
 
The Ring programming language version 1.7 book - Part 39 of 196
The Ring programming language version 1.7 book - Part 39 of 196The Ring programming language version 1.7 book - Part 39 of 196
The Ring programming language version 1.7 book - Part 39 of 196Mahmoud Samir Fayed
 
01 Java Language And OOP Part I LAB
01 Java Language And OOP Part I LAB01 Java Language And OOP Part I LAB
01 Java Language And OOP Part I LABHari Christian
 
DevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreDevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreXavier Coulon
 
Introduction to Python for Plone developers
Introduction to Python for Plone developersIntroduction to Python for Plone developers
Introduction to Python for Plone developersJim Roepcke
 
String and string manipulation x
String and string manipulation xString and string manipulation x
String and string manipulation xShahjahan Samoon
 
Introduction to Groovy (Serbian Developer Conference 2013)
Introduction to Groovy (Serbian Developer Conference 2013)Introduction to Groovy (Serbian Developer Conference 2013)
Introduction to Groovy (Serbian Developer Conference 2013)Joachim Baumann
 
06 Java Language And OOP Part VI
06 Java Language And OOP Part VI06 Java Language And OOP Part VI
06 Java Language And OOP Part VIHari Christian
 
Ti1220 Lecture 7: Polymorphism
Ti1220 Lecture 7: PolymorphismTi1220 Lecture 7: Polymorphism
Ti1220 Lecture 7: PolymorphismEelco Visser
 
FUNDAMENTALS OF PYTHON LANGUAGE
 FUNDAMENTALS OF PYTHON LANGUAGE  FUNDAMENTALS OF PYTHON LANGUAGE
FUNDAMENTALS OF PYTHON LANGUAGE Saraswathi Murugan
 
The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210Mahmoud Samir Fayed
 
Java Polymorphism Part 2
Java Polymorphism Part 2Java Polymorphism Part 2
Java Polymorphism Part 2AathikaJava
 
String handling(string class)
String handling(string class)String handling(string class)
String handling(string class)Ravi Kant Sahu
 

Was ist angesagt? (20)

Sparql
SparqlSparql
Sparql
 
High Wizardry in the Land of Scala
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scala
 
Introduction to the basics of Python programming (part 3)
Introduction to the basics of Python programming (part 3)Introduction to the basics of Python programming (part 3)
Introduction to the basics of Python programming (part 3)
 
The Ring programming language version 1.7 book - Part 39 of 196
The Ring programming language version 1.7 book - Part 39 of 196The Ring programming language version 1.7 book - Part 39 of 196
The Ring programming language version 1.7 book - Part 39 of 196
 
01 Java Language And OOP Part I LAB
01 Java Language And OOP Part I LAB01 Java Language And OOP Part I LAB
01 Java Language And OOP Part I LAB
 
DevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreDevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a Datastore
 
Introduction to Python for Plone developers
Introduction to Python for Plone developersIntroduction to Python for Plone developers
Introduction to Python for Plone developers
 
String and string manipulation x
String and string manipulation xString and string manipulation x
String and string manipulation x
 
Introduction to Groovy (Serbian Developer Conference 2013)
Introduction to Groovy (Serbian Developer Conference 2013)Introduction to Groovy (Serbian Developer Conference 2013)
Introduction to Groovy (Serbian Developer Conference 2013)
 
06 Java Language And OOP Part VI
06 Java Language And OOP Part VI06 Java Language And OOP Part VI
06 Java Language And OOP Part VI
 
Ti1220 Lecture 7: Polymorphism
Ti1220 Lecture 7: PolymorphismTi1220 Lecture 7: Polymorphism
Ti1220 Lecture 7: Polymorphism
 
Strings in java
Strings in javaStrings in java
Strings in java
 
STRINGS IN JAVA
STRINGS IN JAVASTRINGS IN JAVA
STRINGS IN JAVA
 
FUNDAMENTALS OF PYTHON LANGUAGE
 FUNDAMENTALS OF PYTHON LANGUAGE  FUNDAMENTALS OF PYTHON LANGUAGE
FUNDAMENTALS OF PYTHON LANGUAGE
 
Functional concepts in C#
Functional concepts in C#Functional concepts in C#
Functional concepts in C#
 
Pythonppt28 11-18
Pythonppt28 11-18Pythonppt28 11-18
Pythonppt28 11-18
 
The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210The Ring programming language version 1.9 book - Part 39 of 210
The Ring programming language version 1.9 book - Part 39 of 210
 
Why Haskell
Why HaskellWhy Haskell
Why Haskell
 
Java Polymorphism Part 2
Java Polymorphism Part 2Java Polymorphism Part 2
Java Polymorphism Part 2
 
String handling(string class)
String handling(string class)String handling(string class)
String handling(string class)
 

Andere mochten auch

Bluetooth LE: User Experience with iOS
Bluetooth LE: User Experience with iOSBluetooth LE: User Experience with iOS
Bluetooth LE: User Experience with iOSGlobalLogic Ukraine
 
Annual report 2015 web
Annual report 2015 webAnnual report 2015 web
Annual report 2015 webYana Arsenieva
 
Swift testing ftw
Swift testing ftwSwift testing ftw
Swift testing ftwJorge Ortiz
 
Unit testing in swift 2 - The before & after story
Unit testing in swift 2 - The before & after storyUnit testing in swift 2 - The before & after story
Unit testing in swift 2 - The before & after storyJorge Ortiz
 
Testing iOS10 Apps with Appium and its new XCUITest backend
Testing iOS10 Apps with Appium and its new XCUITest backendTesting iOS10 Apps with Appium and its new XCUITest backend
Testing iOS10 Apps with Appium and its new XCUITest backendTestplus GmbH
 
Testing in swift
Testing in swiftTesting in swift
Testing in swifthugo lu
 
Generating test cases using UML Communication Diagram
Generating test cases using UML Communication Diagram Generating test cases using UML Communication Diagram
Generating test cases using UML Communication Diagram Praveen Penumathsa
 
7 Stages of Unit Testing in iOS
7 Stages of Unit Testing in iOS7 Stages of Unit Testing in iOS
7 Stages of Unit Testing in iOSJorge Ortiz
 
iOS advanced architecture workshop 3h edition
iOS advanced architecture workshop 3h editioniOS advanced architecture workshop 3h edition
iOS advanced architecture workshop 3h editionJorge Ortiz
 
Unit testing best practices
Unit testing best practicesUnit testing best practices
Unit testing best practicesnickokiss
 
Unit Testing Concepts and Best Practices
Unit Testing Concepts and Best PracticesUnit Testing Concepts and Best Practices
Unit Testing Concepts and Best PracticesDerek Smith
 
UNIT TESTING PPT
UNIT TESTING PPTUNIT TESTING PPT
UNIT TESTING PPTsuhasreddy1
 

Andere mochten auch (14)

Unit Testing in Swift
Unit Testing in SwiftUnit Testing in Swift
Unit Testing in Swift
 
Bluetooth LE: User Experience with iOS
Bluetooth LE: User Experience with iOSBluetooth LE: User Experience with iOS
Bluetooth LE: User Experience with iOS
 
Annual report 2015 web
Annual report 2015 webAnnual report 2015 web
Annual report 2015 web
 
Swift testing ftw
Swift testing ftwSwift testing ftw
Swift testing ftw
 
Unit testing in swift 2 - The before & after story
Unit testing in swift 2 - The before & after storyUnit testing in swift 2 - The before & after story
Unit testing in swift 2 - The before & after story
 
Testing iOS10 Apps with Appium and its new XCUITest backend
Testing iOS10 Apps with Appium and its new XCUITest backendTesting iOS10 Apps with Appium and its new XCUITest backend
Testing iOS10 Apps with Appium and its new XCUITest backend
 
Testing in swift
Testing in swiftTesting in swift
Testing in swift
 
Generating test cases using UML Communication Diagram
Generating test cases using UML Communication Diagram Generating test cases using UML Communication Diagram
Generating test cases using UML Communication Diagram
 
7 Stages of Unit Testing in iOS
7 Stages of Unit Testing in iOS7 Stages of Unit Testing in iOS
7 Stages of Unit Testing in iOS
 
iOS Unit Testing Like a Boss
iOS Unit Testing Like a BossiOS Unit Testing Like a Boss
iOS Unit Testing Like a Boss
 
iOS advanced architecture workshop 3h edition
iOS advanced architecture workshop 3h editioniOS advanced architecture workshop 3h edition
iOS advanced architecture workshop 3h edition
 
Unit testing best practices
Unit testing best practicesUnit testing best practices
Unit testing best practices
 
Unit Testing Concepts and Best Practices
Unit Testing Concepts and Best PracticesUnit Testing Concepts and Best Practices
Unit Testing Concepts and Best Practices
 
UNIT TESTING PPT
UNIT TESTING PPTUNIT TESTING PPT
UNIT TESTING PPT
 

Ähnlich wie Protocol-Oriented Programming in Swift

Class 2 - Introduction to PHP
Class 2 - Introduction to PHPClass 2 - Introduction to PHP
Class 2 - Introduction to PHPAhmed Swilam
 
SPARQL introduction and training (130+ slides with exercices)
SPARQL introduction and training (130+ slides with exercices)SPARQL introduction and training (130+ slides with exercices)
SPARQL introduction and training (130+ slides with exercices)Thomas Francart
 
PythonStudyMaterialSTudyMaterial.pdf
PythonStudyMaterialSTudyMaterial.pdfPythonStudyMaterialSTudyMaterial.pdf
PythonStudyMaterialSTudyMaterial.pdfdata2businessinsight
 
2. overview of c#
2. overview of c#2. overview of c#
2. overview of c#Rohit Rao
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojureAbbas Raza
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, SwiftYandex
 
TI1220 Lecture 8: Traits & Type Parameterization
TI1220 Lecture 8: Traits & Type ParameterizationTI1220 Lecture 8: Traits & Type Parameterization
TI1220 Lecture 8: Traits & Type ParameterizationEelco Visser
 
Refactoring bad codesmell
Refactoring bad codesmellRefactoring bad codesmell
Refactoring bad codesmellhyunglak kim
 
Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9sagaroceanic11
 
Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9sagaroceanic11
 
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...Maulik Borsaniya
 
TEMPLATES IN JAVA
TEMPLATES IN JAVATEMPLATES IN JAVA
TEMPLATES IN JAVAMuskanSony
 
Scala in practice - 3 years later
Scala in practice - 3 years laterScala in practice - 3 years later
Scala in practice - 3 years laterpatforna
 

Ähnlich wie Protocol-Oriented Programming in Swift (20)

Class 2 - Introduction to PHP
Class 2 - Introduction to PHPClass 2 - Introduction to PHP
Class 2 - Introduction to PHP
 
Lambdas and Laughs
Lambdas and LaughsLambdas and Laughs
Lambdas and Laughs
 
SPARQL introduction and training (130+ slides with exercices)
SPARQL introduction and training (130+ slides with exercices)SPARQL introduction and training (130+ slides with exercices)
SPARQL introduction and training (130+ slides with exercices)
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
PythonStudyMaterialSTudyMaterial.pdf
PythonStudyMaterialSTudyMaterial.pdfPythonStudyMaterialSTudyMaterial.pdf
PythonStudyMaterialSTudyMaterial.pdf
 
Linq Introduction
Linq IntroductionLinq Introduction
Linq Introduction
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
2. overview of c#
2. overview of c#2. overview of c#
2. overview of c#
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
 
Ruby Basics
Ruby BasicsRuby Basics
Ruby Basics
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, Swift
 
Ruby basics
Ruby basicsRuby basics
Ruby basics
 
Of Lambdas and LINQ
Of Lambdas and LINQOf Lambdas and LINQ
Of Lambdas and LINQ
 
TI1220 Lecture 8: Traits & Type Parameterization
TI1220 Lecture 8: Traits & Type ParameterizationTI1220 Lecture 8: Traits & Type Parameterization
TI1220 Lecture 8: Traits & Type Parameterization
 
Refactoring bad codesmell
Refactoring bad codesmellRefactoring bad codesmell
Refactoring bad codesmell
 
Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9
 
Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9
 
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
 
TEMPLATES IN JAVA
TEMPLATES IN JAVATEMPLATES IN JAVA
TEMPLATES IN JAVA
 
Scala in practice - 3 years later
Scala in practice - 3 years laterScala in practice - 3 years later
Scala in practice - 3 years later
 

Mehr von GlobalLogic Ukraine

GlobalLogic JavaScript Community Webinar #18 “Long Story Short: OSI Model”
GlobalLogic JavaScript Community Webinar #18 “Long Story Short: OSI Model”GlobalLogic JavaScript Community Webinar #18 “Long Story Short: OSI Model”
GlobalLogic JavaScript Community Webinar #18 “Long Story Short: OSI Model”GlobalLogic Ukraine
 
Штучний інтелект як допомога в навчанні, а не замінник.pptx
Штучний інтелект як допомога в навчанні, а не замінник.pptxШтучний інтелект як допомога в навчанні, а не замінник.pptx
Штучний інтелект як допомога в навчанні, а не замінник.pptxGlobalLogic Ukraine
 
Задачі AI-розробника як застосовується штучний інтелект.pptx
Задачі AI-розробника як застосовується штучний інтелект.pptxЗадачі AI-розробника як застосовується штучний інтелект.pptx
Задачі AI-розробника як застосовується штучний інтелект.pptxGlobalLogic Ukraine
 
Що треба вивчати, щоб стати розробником штучного інтелекту та нейромереж.pptx
Що треба вивчати, щоб стати розробником штучного інтелекту та нейромереж.pptxЩо треба вивчати, щоб стати розробником штучного інтелекту та нейромереж.pptx
Що треба вивчати, щоб стати розробником штучного інтелекту та нейромереж.pptxGlobalLogic Ukraine
 
GlobalLogic Java Community Webinar #16 “Zaloni’s Architecture for Data-Driven...
GlobalLogic Java Community Webinar #16 “Zaloni’s Architecture for Data-Driven...GlobalLogic Java Community Webinar #16 “Zaloni’s Architecture for Data-Driven...
GlobalLogic Java Community Webinar #16 “Zaloni’s Architecture for Data-Driven...GlobalLogic Ukraine
 
JavaScript Community Webinar #14 "Why Is Git Rebase?"
JavaScript Community Webinar #14 "Why Is Git Rebase?"JavaScript Community Webinar #14 "Why Is Git Rebase?"
JavaScript Community Webinar #14 "Why Is Git Rebase?"GlobalLogic Ukraine
 
GlobalLogic .NET Community Webinar #3 "Exploring Serverless with Azure Functi...
GlobalLogic .NET Community Webinar #3 "Exploring Serverless with Azure Functi...GlobalLogic .NET Community Webinar #3 "Exploring Serverless with Azure Functi...
GlobalLogic .NET Community Webinar #3 "Exploring Serverless with Azure Functi...GlobalLogic Ukraine
 
Страх і сила помилок - IT Inside від GlobalLogic Education
Страх і сила помилок - IT Inside від GlobalLogic EducationСтрах і сила помилок - IT Inside від GlobalLogic Education
Страх і сила помилок - IT Inside від GlobalLogic EducationGlobalLogic Ukraine
 
GlobalLogic .NET Webinar #2 “Azure RBAC and Managed Identity”
GlobalLogic .NET Webinar #2 “Azure RBAC and Managed Identity”GlobalLogic .NET Webinar #2 “Azure RBAC and Managed Identity”
GlobalLogic .NET Webinar #2 “Azure RBAC and Managed Identity”GlobalLogic Ukraine
 
GlobalLogic QA Webinar “What does it take to become a Test Engineer”
GlobalLogic QA Webinar “What does it take to become a Test Engineer”GlobalLogic QA Webinar “What does it take to become a Test Engineer”
GlobalLogic QA Webinar “What does it take to become a Test Engineer”GlobalLogic Ukraine
 
“How to Secure Your Applications With a Keycloak?
“How to Secure Your Applications With a Keycloak?“How to Secure Your Applications With a Keycloak?
“How to Secure Your Applications With a Keycloak?GlobalLogic Ukraine
 
GlobalLogic Machine Learning Webinar “Advanced Statistical Methods for Linear...
GlobalLogic Machine Learning Webinar “Advanced Statistical Methods for Linear...GlobalLogic Machine Learning Webinar “Advanced Statistical Methods for Linear...
GlobalLogic Machine Learning Webinar “Advanced Statistical Methods for Linear...GlobalLogic Ukraine
 
GlobalLogic Machine Learning Webinar “Statistical learning of linear regressi...
GlobalLogic Machine Learning Webinar “Statistical learning of linear regressi...GlobalLogic Machine Learning Webinar “Statistical learning of linear regressi...
GlobalLogic Machine Learning Webinar “Statistical learning of linear regressi...GlobalLogic Ukraine
 
GlobalLogic C++ Webinar “The Minimum Knowledge to Become a C++ Developer”
GlobalLogic C++ Webinar “The Minimum Knowledge to Become a C++ Developer”GlobalLogic C++ Webinar “The Minimum Knowledge to Become a C++ Developer”
GlobalLogic C++ Webinar “The Minimum Knowledge to Become a C++ Developer”GlobalLogic Ukraine
 
Embedded Webinar #17 "Low-level Network Testing in Embedded Devices Development"
Embedded Webinar #17 "Low-level Network Testing in Embedded Devices Development"Embedded Webinar #17 "Low-level Network Testing in Embedded Devices Development"
Embedded Webinar #17 "Low-level Network Testing in Embedded Devices Development"GlobalLogic Ukraine
 
GlobalLogic Webinar "Introduction to Embedded QA"
GlobalLogic Webinar "Introduction to Embedded QA"GlobalLogic Webinar "Introduction to Embedded QA"
GlobalLogic Webinar "Introduction to Embedded QA"GlobalLogic Ukraine
 
C++ Webinar "Why Should You Learn C++ in 2021-22?"
C++ Webinar "Why Should You Learn C++ in 2021-22?"C++ Webinar "Why Should You Learn C++ in 2021-22?"
C++ Webinar "Why Should You Learn C++ in 2021-22?"GlobalLogic Ukraine
 
GlobalLogic Test Automation Live Testing Session “Android Behind UI — Testing...
GlobalLogic Test Automation Live Testing Session “Android Behind UI — Testing...GlobalLogic Test Automation Live Testing Session “Android Behind UI — Testing...
GlobalLogic Test Automation Live Testing Session “Android Behind UI — Testing...GlobalLogic Ukraine
 
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...GlobalLogic Ukraine
 
GlobalLogic Azure TechTalk ONLINE “Marketing Data Lake in Azure”
GlobalLogic Azure TechTalk ONLINE “Marketing Data Lake in Azure”GlobalLogic Azure TechTalk ONLINE “Marketing Data Lake in Azure”
GlobalLogic Azure TechTalk ONLINE “Marketing Data Lake in Azure”GlobalLogic Ukraine
 

Mehr von GlobalLogic Ukraine (20)

GlobalLogic JavaScript Community Webinar #18 “Long Story Short: OSI Model”
GlobalLogic JavaScript Community Webinar #18 “Long Story Short: OSI Model”GlobalLogic JavaScript Community Webinar #18 “Long Story Short: OSI Model”
GlobalLogic JavaScript Community Webinar #18 “Long Story Short: OSI Model”
 
Штучний інтелект як допомога в навчанні, а не замінник.pptx
Штучний інтелект як допомога в навчанні, а не замінник.pptxШтучний інтелект як допомога в навчанні, а не замінник.pptx
Штучний інтелект як допомога в навчанні, а не замінник.pptx
 
Задачі AI-розробника як застосовується штучний інтелект.pptx
Задачі AI-розробника як застосовується штучний інтелект.pptxЗадачі AI-розробника як застосовується штучний інтелект.pptx
Задачі AI-розробника як застосовується штучний інтелект.pptx
 
Що треба вивчати, щоб стати розробником штучного інтелекту та нейромереж.pptx
Що треба вивчати, щоб стати розробником штучного інтелекту та нейромереж.pptxЩо треба вивчати, щоб стати розробником штучного інтелекту та нейромереж.pptx
Що треба вивчати, щоб стати розробником штучного інтелекту та нейромереж.pptx
 
GlobalLogic Java Community Webinar #16 “Zaloni’s Architecture for Data-Driven...
GlobalLogic Java Community Webinar #16 “Zaloni’s Architecture for Data-Driven...GlobalLogic Java Community Webinar #16 “Zaloni’s Architecture for Data-Driven...
GlobalLogic Java Community Webinar #16 “Zaloni’s Architecture for Data-Driven...
 
JavaScript Community Webinar #14 "Why Is Git Rebase?"
JavaScript Community Webinar #14 "Why Is Git Rebase?"JavaScript Community Webinar #14 "Why Is Git Rebase?"
JavaScript Community Webinar #14 "Why Is Git Rebase?"
 
GlobalLogic .NET Community Webinar #3 "Exploring Serverless with Azure Functi...
GlobalLogic .NET Community Webinar #3 "Exploring Serverless with Azure Functi...GlobalLogic .NET Community Webinar #3 "Exploring Serverless with Azure Functi...
GlobalLogic .NET Community Webinar #3 "Exploring Serverless with Azure Functi...
 
Страх і сила помилок - IT Inside від GlobalLogic Education
Страх і сила помилок - IT Inside від GlobalLogic EducationСтрах і сила помилок - IT Inside від GlobalLogic Education
Страх і сила помилок - IT Inside від GlobalLogic Education
 
GlobalLogic .NET Webinar #2 “Azure RBAC and Managed Identity”
GlobalLogic .NET Webinar #2 “Azure RBAC and Managed Identity”GlobalLogic .NET Webinar #2 “Azure RBAC and Managed Identity”
GlobalLogic .NET Webinar #2 “Azure RBAC and Managed Identity”
 
GlobalLogic QA Webinar “What does it take to become a Test Engineer”
GlobalLogic QA Webinar “What does it take to become a Test Engineer”GlobalLogic QA Webinar “What does it take to become a Test Engineer”
GlobalLogic QA Webinar “What does it take to become a Test Engineer”
 
“How to Secure Your Applications With a Keycloak?
“How to Secure Your Applications With a Keycloak?“How to Secure Your Applications With a Keycloak?
“How to Secure Your Applications With a Keycloak?
 
GlobalLogic Machine Learning Webinar “Advanced Statistical Methods for Linear...
GlobalLogic Machine Learning Webinar “Advanced Statistical Methods for Linear...GlobalLogic Machine Learning Webinar “Advanced Statistical Methods for Linear...
GlobalLogic Machine Learning Webinar “Advanced Statistical Methods for Linear...
 
GlobalLogic Machine Learning Webinar “Statistical learning of linear regressi...
GlobalLogic Machine Learning Webinar “Statistical learning of linear regressi...GlobalLogic Machine Learning Webinar “Statistical learning of linear regressi...
GlobalLogic Machine Learning Webinar “Statistical learning of linear regressi...
 
GlobalLogic C++ Webinar “The Minimum Knowledge to Become a C++ Developer”
GlobalLogic C++ Webinar “The Minimum Knowledge to Become a C++ Developer”GlobalLogic C++ Webinar “The Minimum Knowledge to Become a C++ Developer”
GlobalLogic C++ Webinar “The Minimum Knowledge to Become a C++ Developer”
 
Embedded Webinar #17 "Low-level Network Testing in Embedded Devices Development"
Embedded Webinar #17 "Low-level Network Testing in Embedded Devices Development"Embedded Webinar #17 "Low-level Network Testing in Embedded Devices Development"
Embedded Webinar #17 "Low-level Network Testing in Embedded Devices Development"
 
GlobalLogic Webinar "Introduction to Embedded QA"
GlobalLogic Webinar "Introduction to Embedded QA"GlobalLogic Webinar "Introduction to Embedded QA"
GlobalLogic Webinar "Introduction to Embedded QA"
 
C++ Webinar "Why Should You Learn C++ in 2021-22?"
C++ Webinar "Why Should You Learn C++ in 2021-22?"C++ Webinar "Why Should You Learn C++ in 2021-22?"
C++ Webinar "Why Should You Learn C++ in 2021-22?"
 
GlobalLogic Test Automation Live Testing Session “Android Behind UI — Testing...
GlobalLogic Test Automation Live Testing Session “Android Behind UI — Testing...GlobalLogic Test Automation Live Testing Session “Android Behind UI — Testing...
GlobalLogic Test Automation Live Testing Session “Android Behind UI — Testing...
 
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
GlobalLogic Test Automation Online TechTalk “Test Driven Development as a Per...
 
GlobalLogic Azure TechTalk ONLINE “Marketing Data Lake in Azure”
GlobalLogic Azure TechTalk ONLINE “Marketing Data Lake in Azure”GlobalLogic Azure TechTalk ONLINE “Marketing Data Lake in Azure”
GlobalLogic Azure TechTalk ONLINE “Marketing Data Lake in Azure”
 

Kürzlich hochgeladen

ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 

Kürzlich hochgeladen (20)

ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 

Protocol-Oriented Programming in Swift

  • 1. 1
  • 2. 2 Protocol-oriented programming in Swift Rostyslav Kobyzskyi Software Engineer 16th Nov, 2016
  • 3. 3 1. Classes and problems 2. Start with Protocol 3. Using Protocols 4. Examples 5. Questions Agenda
  • 4. Dave Abrahams • David Abrahams is a computer programmer and author • Abrahams became a member of the C++ Standards Committee in 1996 • In 2013 Abrahams became an employee at Apple Inc, where he is involved in the development of the Swift programming language
  • 6. Classes • Encapsulation • Access Control • Abstraction • Namespace • Expressive Syntax • Extensibility
  • 7. Classes • Encapsulation • Access Control • Abstraction • Namespace • Expressive Syntax • Extensibility
  • 15. 1. Implicit Sharing • Defensive Copy • Inefficiency • Race Condition • Locks • More Inefficiency • Deadlock • Complexity • Bugs!
  • 16. Values don’t Share. That’s a good thing Classes? They overshare…
  • 19. Instance 2. Inheritance One superclass Single Inheritance Subclass Stored Properties Superclass
  • 20. Instance 2. Inheritance One superclass Single Inheritance Super class may have Stored Properties Subclass Stored Properties Superclass Stored Properties
  • 21. Instance 2. Inheritance One superclass Single Inheritance Super class may have Stored Properties • You must accept them Subclass Stored Properties Superclass Stored Properties
  • 22. 2. Inheritance One superclass Single Inheritance Super class may have Stored Properties • You must accept them • Initialization problem Instance Subclass Stored Properties Superclass Stored Properties
  • 23. 2. Inheritance One superclass Single Inheritance Super class may have Stored Properties • You must accept them • Initialization problem • Don’t break superclass invariants! Instance Subclass Stored Properties Superclass Stored Properties
  • 24. 2. Inheritance One superclass Single Inheritance Super class may have Stored Properties • You must accept them • Initialization problem • Don’t break superclass invariants! Know what/how to override (and when not) Instance Subclass Stored Properties Superclass Stored Properties
  • 25. 3. Lost Type Relationships class Ordered { func precedes(other: Ordered) -> Bool } func binarySearch(sortedKeys: [Ordered], forKey k: Ordered) -> Int { var lo = 0, hi = sortedKeys.count while hi > lo { let mid = lo + (hi - lo) / 2 if sortedKeys[mid].precedes(k) { lo = mid + 1 } else { hi = mid } } return lo }
  • 26. 3. Lost Type Relationships class Ordered { func precedes(other: Ordered) -> Bool { } }
  • 27. 3. Lost Type Relationships class Ordered { func precedes(other: Ordered) -> Bool } { fatalError(“implement me!”) }
  • 28. 3. Lost Type Relationships class Ordered { func precedes(other: Ordered) -> Bool } { fatalError(“implement me!”) } X
  • 29. 3. Lost Type Relationships class Ordered { func precedes(other: Ordered) -> Bool } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < other.value } } { fatalError(“implement me!”) } X
  • 30. class Ordered { func precedes(other: Ordered) -> Bool } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < other.value } } 3. Lost Type Relationships { fatalError(“implement me!”) } X
  • 31. class Ordered { func precedes(other: Ordered) -> Bool } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < other.value } } 3. Lost Type Relationships { fatalError(“implement me!”) } X
  • 32. class Ordered { func precedes(other: Ordered) -> Bool } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < other.value } } 3. Lost Type Relationships { fatalError(“implement me!”) } X `Ordered` does not have a member named `value`
  • 33. `Ordered` does not have a member named `value` 3. Lost Type Relationships { fatalError(“implement me!”) } X class Ordered { func precedes(other: Ordered) -> Bool } class Label: Ordered { var text: String = “” ... } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < other.value } }
  • 34. class Ordered { func precedes(other: Ordered) -> Bool } class Label: Ordered { var text: String = “” ... } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < (other as! Number).value } } 3. Lost Type Relationships { fatalError(“implement me!”) } X
  • 35. A better Abstraction Mechanism • Support value types (and classes) • Support static type relationships (and dynamic dispatch) • Non-monolithic • Doesn’t impose instance data on models • Doesn’t impose initialization burdens on models • Makes clear what to implement
  • 37. Start with a Protocol
  • 38. Starting override with Protocols class Ordered { func precedes(other: Ordered) -> Bool } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < other.value } } { fatalError(“implement me!”) } X
  • 39. Starting override with Protocols class Ordered { func precedes(other: Ordered) -> Bool } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < (other as! Number).value } } { fatalError(“implement me!”) } X
  • 40. Starting override with Protocols protocol Ordered { func precedes(other: Ordered) -> Bool } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < (other as! Number).value } } { fatalError(“implement me!”) } X
  • 41. Starting override with Protocols protocol Ordered { func precedes(other: Ordered) -> Bool } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < (other as! Number).value } } { fatalError(“implement me!”) } Protocol methods may not have bodies
  • 42. Starting override with Protocols protocol Ordered { func precedes(other: Ordered) -> Bool } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < (other as! Number).value } } Method does not override any method from superclass
  • 43. Starting override with Protocols protocol Ordered { func precedes(other: Ordered) -> Bool } class Number: Ordered { var value: Double = 0 override fund precedes(other: Ordered) -> Bool { return value < (other as! Number).value} }
  • 44. Starting override with Protocols protocol Ordered { func precedes(other: Ordered) -> Bool } struct Number: Ordered { var value: Double = 0 fund precedes(other: Ordered) -> Bool { return value < (other as! Number).value } }
  • 45. Starting override with Protocols protocol Ordered { func precedes(other: Ordered) -> Bool } struct Number: Ordered { var value: Double = 0 fund precedes(other: Ordered) -> Bool { return value < (other as! Number).value } }
  • 46. Starting override with Protocols protocol Ordered { func precedes(other: Ordered) -> Bool } struct Number: Ordered { var value: Double = 0 fund precedes(other: Number) -> Bool { return value < other.value } }
  • 47. Starting override with Protocols protocol Ordered { func precedes(other: Ordered) -> Bool } struct Number: Ordered { var value: Double = 0 fund precedes(other: Number) -> Bool { return value < other.value } } Protocol requires function ‘precedes’ with type ‘(Oredered)’ -> Bool candidate has non-matching type (`Number`) -> Bool
  • 48. Starting override with Protocols protocol Ordered { func precedes(other: Self) -> Bool } struct Number: Ordered { var value: Double = 0 fund precedes(other: Number) -> Bool { return value < other.value } } Self requirement
  • 49. Using out Protocol func binarySearch(sortedKeys: [Ordered], forKey k: Ordered) -> Int { var lo = 0, hi = sortedKeys.count while hi > lo { let mid = lo + (hi - lo) / 2 if sortedKeys[mid].precedes(k) { lo = mid + 1 } else { hi = mid } } return lo }
  • 50. Using out Protocol func binarySearch(sortedKeys: [Ordered], forKey k: Ordered) -> Int { var lo = 0, hi = sortedKeys.count while hi > lo { let mid = lo + (hi - lo) / 2 if sortedKeys[mid].precedes(k) { lo = mid + 1 } else { hi = mid } } return lo } Protocol ‘Ordered’ can only be used as a generic constraint because if has Self or associated type requirements
  • 51. Using out Protocol func binarySearch(sortedKeys: [Ordered], forKey k: Ordered) -> Int { var lo = 0, hi = sortedKeys.count while hi > lo { let mid = lo + (hi - lo) / 2 if sortedKeys[mid].precedes(k) { lo = mid + 1 } else { hi = mid } } return lo } Protocol ‘Ordered’ can only be used as a generic constraint because if has Self or associated type requirements
  • 52. Using out Protocol func binarySearch<T: Ordered>(sortedKeys: [T], forKey k: T) -> Int { var lo = 0, hi = sortedKeys.count while hi > lo { let mid = lo + (hi - lo) / 2 if sortedKeys[mid].precedes(k) { lo = mid + 1 } else { hi = mid } } return lo }
  • 53. Two-world of Protocols Without Self Requirement With Self Requirement func precedes(other: Ordered) -> Bool func precedes(other: Self) -> Bool
  • 54. Two-world of Protocols Without Self Requirement With Self Requirement func precedes(other: Ordered) -> Bool Usable as a type sort(inout a: [Ordered]) func precedes(other: Self) -> Bool Only usable as a generic constraint sort<T: Ordered>(inout a: [T])
  • 55. Two-world of Protocols Without Self Requirement With Self Requirement func precedes(other: Ordered) -> Bool Usable as a type sort(inout a: [Ordered]) Every model must deal with all others func precedes(other: Self) -> Bool Only usable as a generic constraint sort<T: Ordered>(inout a: [T]) Models are free from interaction
  • 56. Two-world of Protocols Without Self Requirement With Self Requirement func precedes(other: Ordered) -> Bool Usable as a type sort(inout a: [Ordered]) Every model must deal with all others Dynamic dispatch func precedes(other: Self) -> Bool Only usable as a generic constraint sort<T: Ordered>(inout a: [T]) Models are free from interaction Static dispatch
  • 57. Two-world of Protocols Without Self Requirement With Self Requirement func precedes(other: Ordered) -> Bool Usable as a type sort(inout a: [Ordered]) Every model must deal with all others Dynamic dispatch Less optimizable func precedes(other: Self) -> Bool Only usable as a generic constraint sort<T: Ordered>(inout a: [T]) Models are free from interaction Static dispatch More optimizable
  • 58. A Primitive “Render” struct Renderer { func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) } func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) } func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) { print(“arcAt((center), radius: (radius)),” + + “ startAngle: (startAngle), endAngle: (endAngle)”) } }
  • 59. Drawable protocol Drawable { func draw(randerer: Renderer) }
  • 60. Polygon protocol Drawable { func draw(randerer: Renderer) } struct Polygon: Drawable { func draw(renderer: Renderer) { renderer.moveTo(corners.last!) for p in corners { renderer.lineTo(p) } } var corners: [CGPoint] = [] }
  • 61. Circle protocol Drawable { func draw(randerer: Renderer) } struct Circle: Drawable { func draw(renderer: Renderer) { renderer.artAt(center, radius: radius, startAngle: 0.0, endAngle: twoPi) } } var center: CGPoint var radius: CGFloat }
  • 62. Diagram protocol Drawable { func draw(randerer: Renderer) } struct Diagram: Drawable { func draw(renderer: Renderer) { for f in elements { f.draw(renderer) } } var elements: [Drawable] = [] }
  • 63. Test It! var circle = Circle( center: CGPoint(x: 187.5, y: 333.5), radius: 93.75 )
  • 64. Test It! var circle = Circle( center: CGPoint(x: 187.5, y: 333.5), radius: 93.75 ) var triangle = Polygon(corners: [ CGPoint(x: 187.5, y: 427.25), CGPoint(x: 268.69, y: 286.625), CGPoint(x: 106.31, y: 286.625) ])
  • 65. Test It! var circle = Circle( center: CGPoint(x: 187.5, y: 333.5), radius: 93.75 ) var triangle = Polygon(corners: [ CGPoint(x: 187.5, y: 427.25), CGPoint(x: 268.69, y: 286.625), CGPoint(x: 106.31, y: 286.625) ]) var diagram = Diagram(elements: [circle: triangle])
  • 66. Test It! var circle = Circle( center: CGPoint(x: 187.5, y: 333.5), radius: 93.75 ) var triangle = Polygon(corners: [ CGPoint(x: 187.5, y: 427.25), CGPoint(x: 268.69, y: 286.625), CGPoint(x: 106.31, y: 286.625) ]) var diagram = Diagram(elements: [circle: triangle]) diagram.draw(Renderer())
  • 67. Renderer as Protocol struct Renderer { func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) } func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) } func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) { print(“arcAt((center), radius: (radius)),” + + “ startAngle: (startAngle), endAngle: (endAngle)”) } } struct Renderer { func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) } func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) } func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) { print(“arcAt((center), radius: (radius)),” + + “ startAngle: (startAngle), endAngle: (endAngle)”) } }
  • 68. Renderer as Protocol protocol Renderer { func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) } func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) } func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) { print(“arcAt((center), radius: (radius)),” + + “ startAngle: (startAngle), endAngle: (endAngle)”) } } struct Renderer { func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) } func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) } func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) { print(“arcAt((center), radius: (radius)),” + + “ startAngle: (startAngle), endAngle: (endAngle)”) } }
  • 69. Renderer as Protocol protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) } struct Renderer { func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) } func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) } func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) { print(“arcAt((center), radius: (radius)),” + + “ startAngle: (startAngle), endAngle: (endAngle)”) } }
  • 70. Renderer as Protocol protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) } struct Renderer { func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) } func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) } func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) { print(“arcAt((center), radius: (radius)),” + + “ startAngle: (startAngle), endAngle: (endAngle)”) } }
  • 71. Renderer as Protocol protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) } struct TestRenderer: Renderer { func moveTo(p: CGPoint) { print(“moveTo((p.x), (p.y))”) } func lineTo(p: CGPoint) { print(“lineTo((p.x), (p.y))”) } func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) { print(“arcAt((center), radius: (radius)),” + + “ startAngle: (startAngle), endAngle: (endAngle)”) } }
  • 72. Rendering with CoreGraphics Retroactive modeling protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) }
  • 73. Rendering with CoreGraphics Retroactive modeling protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) }
  • 74. Rendering with CoreGraphics Retroactive modeling protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) } extension CGContext: Renderer { func moveTo(p: CGPoint) { } func lineTo(p: CGPoint) { } func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) { } }
  • 75. Rendering with CoreGraphics Retroactive modeling extension CGContext: Renderer { func moveTo(p: CGPoint) { CGContextMoveToPoint(self, p.x, p.y) } func lineTo(p: CGPoint) { CGContextAddLineToPoint(self, p.x, p.y) } func arcAt(center: CGPoint, radius: CGFloat, startAngler: CGFloat, endAngle: CGFloat) { let arc = CGPathCreateMutable() CGPathAddArc(arc, nil, center.x, center.y, radius, startAngle, endAngle, true) CGContextAddPath(self, arc) } }
  • 76. Protocols and Generics for Testability So much better than mocks struct Bubble: Drawable { func draw(r: Renderer) { r.arcAt(center, radius, startAngle: 0, endAngle: twoPi) r.arcAt(highlightCenter, radius: highlightRadius, startAngle: 0, endAngle: twoPi ) } }
  • 77. Protocols and Generics for Testability So much better than mocks struct Bubble: Drawable { func draw(r: Renderer) { r.arcAt(center, radius, startAngle: 0, endAngle: twoPi) r.arcAt(highlightCenter, radius: highlightRadius, startAngle: 0, endAngle: twoPi ) } } struct Circle: Drawable { func draw(r: Renderer) { r.arcAt(center, radius, startAngle: 0, endAngle: twoPi) } }
  • 78. Protocols and Generics for Testability So much better than mocks struct Bubble: Drawable { func draw(r: Renderer) { r.circleAt(center, radius) r.arcAt(highlightCenter, radius: highlightRadius) } } struct Circle: Drawable { func draw(r: Renderer) { r.circleAt(center, radius) } }
  • 79. Adding a Circle Primitive protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func arcAt( center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat) ) }
  • 80. Adding a Circle Primitive protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func arcAt( center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat) ) }
  • 81. Adding a Circle Primitive protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func circleAt(center: CGPoint, radius: CGFloat) func arcAt( center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat) ) }
  • 82. Adding a Circle Primitive protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func circleAt(center: CGPoint, radius: CGFloat) func arcAt( center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat) ) } New requirement
  • 83. Adding a Circle Primitive protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func circleAt(center: CGPoint, radius: CGFloat) func arcAt( center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat) ) } extension TestRenderer { func circleAt(center: CGPoint, radius: CGFloat) { arcAt(center, radius: radius, startAngle: 0, endAngle: twoPi) } }
  • 84. Adding a Circle Primitive protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func circleAt(center: CGPoint, radius: CGFloat) func arcAt( center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat) ) } extension CGContext { func circleAt(center: CGPoint, radius: CGFloat) { arcAt(center, radius: radius, startAngle: 0, endAngle: twoPi) } }
  • 85. Protocol Extension protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func circleAt(center: CGPoint, radius: CGFloat) func arcAt( center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat) ) } extension Renderer { func circleAt(center: CGPoint, radius: CGFloat) { arcAt(center, radius: radius, startAngle: 0, endAngle: twoPi) } } New!
  • 86. Protocol Extension protocol Renderer { func moveTo(p: CGPoint) func lineTo(p: CGPoint) func circleAt(center: CGPoint, radius: CGFloat) func arcAt( center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat) ) } extension Renderer { func circleAt(center: CGPoint, radius: CGFloat) { arcAt(center, radius: radius, startAngle: 0, endAngle: twoPi) } } Shared Implementation
  • 87. Protocol Extension extension Renderer { func circleAt(center: CGPoint, radius: CGFloat) { ... } func rectagleAt(edges: CGRect) { ... } } extension TestRenderer: Renderer { func circleAt(center: CGPoint, radius: CGFloat) { ... } func rectagleAt(edges: CGRect) { ... } }
  • 88. Protocol Extension extension Renderer { func circleAt(center: CGPoint, radius: CGFloat) { ... } func rectagleAt(edges: CGRect) { ... } } extension TestRenderer: Renderer { func circleAt(center: CGPoint, radius: CGFloat) { ... } func rectagleAt(edges: CGRect) { ... } } let r = TestRenderer() r.circleAt(origin, radius: 1) r.rectangleAt(edges)
  • 89. Protocol Extension extension Renderer { func circleAt(center: CGPoint, radius: CGFloat) { ... } func rectagleAt(edges: CGRect) { ... } } extension TestRenderer: Renderer { func circleAt(center: CGPoint, radius: CGFloat) { ... } func rectagleAt(edges: CGRect) { ... } } let r = TestRenderer() r.circleAt(origin, radius: 1) r.rectangleAt(edges)
  • 90. Protocol Extension customization point extension Renderer { func circleAt(center: CGPoint, radius: CGFloat) { ... } func rectagleAt(edges: CGRect) { ... } } extension TestRenderer: Renderer { func circleAt(center: CGPoint, radius: CGFloat) { ... } func rectagleAt(edges: CGRect) { ... } } let r: Renderer = TestRenderer() r.circleAt(origin, radius: 1) r.rectangleAt(edges)