SlideShare ist ein Scribd-Unternehmen logo
1 von 39
Downloaden Sie, um offline zu lesen
Why the Dark Side
should use Swift and
a SOLID Architecture
Jorge D. Ortiz-Fuentes
@jdortiz
#SwiftDarkSide
A Canonical
Examples
production
#SwiftDarkSide
#SwiftDarkSide
Agenda
The Weaknesses of the Dark Side
SOLID Architecture
Design patterns
Weaknesses
of the Dark
Side
Conspiracy Theory
Agility and the MVP
Moving a Planet
SPoF
Whose blame is
that?
Framework
dependency
Teams can hardly
work together
Do you see
any
problems?
#SwiftDarkSide
Needs to Address
Fast growth
Robustness
• testable
• decoupled
• debuggable
(blame)
Team collaboration
Reusable
Defer decisions
Replaceable
frameworks
There is a way:
SOLID Principles
AKA
Clean
Architecture
I find your lack of
faith disturbing
SOLID
Architecture
Clean Architecture
AppDelegate
View (VC) Presenter Interactor Entity Gateway
Connector
#SwiftDarkSide
Single Responsibility
MVC is not enough
More classes, but more cohesive: only one
reason to change
#SwiftDarkSide
Business Logic
import Foundation
class ShowAllSpeakersInteractor {
// MARK: - Properties
let entityGateway: EntityGatewayFetchSpeakersProtocol
weak var presenter: SpeakersListPresenterProtocol?
// MARK: - Initializers
init(entityGateway: EntityGatewayFetchSpeakersProtocol) {
self.entityGateway = entityGateway
}
}
extension ShowAllSpeakersInteractor: InteractorCommandProtocol {
func execute() {
let entities = entityGateway.fetchAllSpeakers()
let displayData = entities.map({entity in
return SpeakerDisplayData(speaker: entity)})
presenter?.presentAllSpeakers(displayData)
}
}
#SwiftDarkSide
Open Close
Open to Extension, Closed to Modification
#SwiftDarkSide
class SpeakersTableViewController:
UITableViewController, SegueHandlerTypeProtocol {
static let speakerCellIdentifier = "SpeakerCell"
var eventHandler:
SpeakersListEventHandlerProtocol?
var numberOfRows = 0
override func viewDidLoad() {
super.viewDidLoad()
eventHandler?.viewDidLoad()
}
override func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return numberOfRows
}
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell {
let cell =
tableView.dequeueReusableCellWithIdentifier(SpeakersTa
bleViewController.speakerCellIdentifier, forIndexPath:
indexPath) as! SpeakerTableViewCell
eventHandler?.presentCell(cell, indexPath:
indexPath)
return cell
}
}
extension SpeakersTableViewController:
SpeakersListViewProtocol {
func
configureListWithNumberOfRows(numberOfRows
: Int) {
self.numberOfRows = numberOfRows
}
func addRowsAtIndexPaths(indexPaths:
[NSIndexPath]) {
self.tableView.insertRowsAtIndexPaths(inde
xPaths, withRowAnimation:
UITableViewRowAnimation.Automatic)
}
}
Passive View
#SwiftDarkSide
Liskov Substitution
It should be possible to use derived classes
without special care
#SwiftDarkSide
extension SpeakersListsPresenter:
SpeakersListEventHandlerProtocol {
func viewDidLoad() {
interactor.execute()
}
func presentCell(cell:
SpeakerCellProtocol, indexPath:
NSIndexPath) {
let index = indexPath.row
guard index < speakers.count else {
return }
let speaker = speakers[index]
cell.displayName(speaker.name)
cell.displayTitle(speaker.title)
cell.displayDateSubmitted(relativeDateStrin
gFromDate(speaker.dateSubmitted))
}
}
Presentation
class SpeakersListsPresenter {
weak var view: SpeakersListViewProtocol?
let interactor: ShowAllSpeakersInteractor
private var speakers: [SpeakerDisplayData]=[]
// MARK: - Initializer
init(interactor: ShowAllSpeakersInteractor,
deleteInteractor: DeleteSpeakerInteractorProtocol) {
self.interactor = interactor
}
}
extension SpeakersListsPresenter:
SpeakersListPresenterProtocol {
func presentAllSpeakers(speakers:
[SpeakerDisplayData]) {
view?.configureListWithNumberOfRows(speakers.count)
self.speakers = speakers
let addedIndexPaths = speakers.enumerate()
.map({(index, _) in return
NSIndexPath(forRow: index, inSection: 0)})
view?.addRowsAtIndexPaths(addedIndexPaths)
}
}
#SwiftDarkSide
Interface Segregation
Don’t force a class to depend on methods
that it won’t use
One interactor will not likely use every
functionality of the entity gateway
#SwiftDarkSide
class InMemorySpeakersRepo {
// MARK: - Properties
var speakers: [Speaker] = []
init() {
}
}
extension InMemorySpeakersRepo: EntityGatewayFetchSpeakersProtocol {
func fetchAllSpeakers() -> [Speaker] {
return speakers
}
}
extension InMemorySpeakersRepo: EntityGatewayCreateSpeakerProtocol {
func createSpeaker(name name: String, title: String, synopsis: String, dateSubmitted: NSDate) {
let id = IdentityGenerator.newUUID()
speakers.append(Speaker(id: id, name: name, title: title, synopsis: synopsis, dateSubmitted:
dateSubmitted))
}
}
extension InMemorySpeakersRepo: EntityGatewayDeleteSpeakerProtocol {
func deleteSpeaker(id: String) {
speakers = speakers.filter { speaker in speaker.id != id }
}
}
Different Functions of the
Entity Gateway
#SwiftDarkSide
Dependency Inversion
The business case SHOULDN’T depend on
the frameworks
#SwiftDarkSide
Deletion Use Case
class DeleteSpeakerInteractor {
let entityGateway: EntityGatewayDeleteSpeakerProtocol
var id: String?
init(entityGateway: EntityGatewayDeleteSpeakerProtocol) {
self.entityGateway = entityGateway
}
}
extension DeleteSpeakerInteractor : InteractorCommandProtocol {
func execute() {
guard let id = self.id else { return }
entityGateway.deleteSpeaker(id)
}
}
Design
Patterns
Take me Outta Here
func presentCell(cell: SpeakerCellProtocol, indexPath:
NSIndexPath) {
let index = indexPath.row
guard index < speakers.count else { return }
let speaker = speakers[index]
cell.displayName(speaker.name)
cell.displayTitle(speaker.title)
cell.displayDateSubmitted(relativeDateStringFromDate(s
peaker.dateSubmitted))
}
Know
That!
var control = Houston(fuel: 1.0,
astronaut: nil, spaceshipOK: true)
do {
try control.launchSpaceship()
} catch Houston.LaunchError.NoFuel {
// Add Fuel
print("Adding fuel")
} catch
Houston.LaunchError.NoAstronaut {
print("Next in line")
} catch
Houston.LaunchError.BrokenShip(let
problem) {
print(problem)
} catch let unknowError {
//
}
Ready for Life
class Houston {
let fuel: Double
let astronaut: String
let spaceshipOK: Bool
init (fuel: Double, astronaut: String?,
spaceshipOK: Bool) {
self.fuel = fuel
self.astronaut = astronaut ?? ""
self.spaceshipOK = spaceshipOK
}
enum LaunchError: ErrorType {
case NoFuel, NoAstronaut, BrokenShip(String)
}
func launchSpaceship() throws {
guard fuel >= 1.0 else { throw
LaunchError.NoFuel }
guard astronaut != "" else { throw
LaunchError.NoAstronaut }
guard spaceshipOK else { throw
LaunchError.BrokenShip("Engine") }
print("Launching spaceship")
}
}
Know
That!
class Text {
func displayContents() {
print("Hola")
}
}
class NullText: Text {
override func displayContents() {
print(“Not much here")
}
}
func fetchText() -> Text {
return NullText()
}
let text = fetchText()
text.displayContents()
Null Object
class Text {
func displayContents() {
print("Hola")
}
}
func fetchText() -> Text? {
return nil
}
if let text = fetchText() {
text.displayContents()
}
Poor Template
class PoorTrooper {
func getIntoSpaceShip() { print("Commencing countdown engines on") }
func conquer(target: String) {
fatalError()
}
func comeBack() { print("Planet earth is blue") }
func attack(target: String) {
getIntoSpaceShip()
conquer(target)
comeBack()
}
}
let cloneTrooper = PoorTrooper()
cloneTrooper.attack("Alderaan")
Swifty Template
protocol Trooper {
func getIntoSpaceShip()
func conquer(target: String)
func comeBack()
func attack(target: String)
}
extension Trooper {
func getIntoSpaceShip() { print("Commencing countdown engines on") }
func comeBack() { print("Planet earth is blue") }
func attack(target: String) {
getIntoSpaceShip()
conquer(target)
comeBack()
}
}
class StormTrooper: Trooper {
func conquer(target: String) { print("Become part of the Empire, (target)") }
}
let finn = StormTrooper()
finn.attack("Tatooine")
Next Steps
#SwiftDarkSide
Recommendations
Pay attention to your architecture; It
always pays off
Use Principles to take decisions
Take advantage of the language and adapt
the patterns to it
In case of doubt, ask for an architecture
loan and ship it
canonicalexamples.com
coupon:
APPSTERDAMERS16
Thank
you!
@jdortiz
#SwiftDarkSide

Weitere ähnliche Inhalte

Was ist angesagt?

DBI-Assisted Android Application Reverse Engineering
DBI-Assisted Android Application Reverse EngineeringDBI-Assisted Android Application Reverse Engineering
DBI-Assisted Android Application Reverse EngineeringSahil Dhar
 
Gwt and JSR 269's Pluggable Annotation Processing API
Gwt and JSR 269's Pluggable Annotation Processing APIGwt and JSR 269's Pluggable Annotation Processing API
Gwt and JSR 269's Pluggable Annotation Processing APIArnaud Tournier
 
Infinum Android Talks #14 - How (not) to get f***** by checkstyle, pdm, findb...
Infinum Android Talks #14 - How (not) to get f***** by checkstyle, pdm, findb...Infinum Android Talks #14 - How (not) to get f***** by checkstyle, pdm, findb...
Infinum Android Talks #14 - How (not) to get f***** by checkstyle, pdm, findb...Infinum
 
DIC To The Limit – deSymfonyDay, Barcelona 2014
DIC To The Limit – deSymfonyDay, Barcelona 2014DIC To The Limit – deSymfonyDay, Barcelona 2014
DIC To The Limit – deSymfonyDay, Barcelona 2014Ronny López
 
Pentesting Android Apps using Frida (Beginners)
Pentesting Android Apps using Frida (Beginners)Pentesting Android Apps using Frida (Beginners)
Pentesting Android Apps using Frida (Beginners)Chandrapal Badshah
 
Java history, versions, types of errors and exception, quiz
Java history, versions, types of errors and exception, quiz Java history, versions, types of errors and exception, quiz
Java history, versions, types of errors and exception, quiz SAurabh PRajapati
 
Prg 421 guide focus dreams prg421guide.com
Prg 421 guide focus dreams   prg421guide.comPrg 421 guide focus dreams   prg421guide.com
Prg 421 guide focus dreams prg421guide.comchandika6
 
Refactoring a go project
Refactoring a go projectRefactoring a go project
Refactoring a go projectDan Tran
 
Improving DroidBox
Improving DroidBoxImproving DroidBox
Improving DroidBoxKelwin Yang
 
Introduction to Dynamic Analysis of Android Application
Introduction to Dynamic Analysis of Android ApplicationIntroduction to Dynamic Analysis of Android Application
Introduction to Dynamic Analysis of Android ApplicationKelwin Yang
 
Understanding Java Dynamic Proxies
Understanding Java Dynamic ProxiesUnderstanding Java Dynamic Proxies
Understanding Java Dynamic ProxiesRafael Luque Leiva
 
From zero to hero with React Native!
From zero to hero with React Native!From zero to hero with React Native!
From zero to hero with React Native!Commit University
 
JPA 스터디 Week2 - Object Relational Mapping
JPA 스터디 Week2 - Object Relational MappingJPA 스터디 Week2 - Object Relational Mapping
JPA 스터디 Week2 - Object Relational MappingCovenant Ko
 
Java notes | All Basics |
Java notes | All Basics |Java notes | All Basics |
Java notes | All Basics |ShubhamAthawane
 
Type Annotations in Java 8
Type Annotations in Java 8 Type Annotations in Java 8
Type Annotations in Java 8 FinLingua, Inc.
 
JavaOne 2017 CON3276 - Selenium Testing Patterns Reloaded
JavaOne 2017 CON3276 - Selenium Testing Patterns ReloadedJavaOne 2017 CON3276 - Selenium Testing Patterns Reloaded
JavaOne 2017 CON3276 - Selenium Testing Patterns ReloadedJorge Hidalgo
 

Was ist angesagt? (20)

DBI-Assisted Android Application Reverse Engineering
DBI-Assisted Android Application Reverse EngineeringDBI-Assisted Android Application Reverse Engineering
DBI-Assisted Android Application Reverse Engineering
 
Gwt and JSR 269's Pluggable Annotation Processing API
Gwt and JSR 269's Pluggable Annotation Processing APIGwt and JSR 269's Pluggable Annotation Processing API
Gwt and JSR 269's Pluggable Annotation Processing API
 
Infinum Android Talks #14 - How (not) to get f***** by checkstyle, pdm, findb...
Infinum Android Talks #14 - How (not) to get f***** by checkstyle, pdm, findb...Infinum Android Talks #14 - How (not) to get f***** by checkstyle, pdm, findb...
Infinum Android Talks #14 - How (not) to get f***** by checkstyle, pdm, findb...
 
DIC To The Limit – deSymfonyDay, Barcelona 2014
DIC To The Limit – deSymfonyDay, Barcelona 2014DIC To The Limit – deSymfonyDay, Barcelona 2014
DIC To The Limit – deSymfonyDay, Barcelona 2014
 
Pentesting Android Apps using Frida (Beginners)
Pentesting Android Apps using Frida (Beginners)Pentesting Android Apps using Frida (Beginners)
Pentesting Android Apps using Frida (Beginners)
 
Java history, versions, types of errors and exception, quiz
Java history, versions, types of errors and exception, quiz Java history, versions, types of errors and exception, quiz
Java history, versions, types of errors and exception, quiz
 
Prg 421 guide focus dreams prg421guide.com
Prg 421 guide focus dreams   prg421guide.comPrg 421 guide focus dreams   prg421guide.com
Prg 421 guide focus dreams prg421guide.com
 
Refactoring a go project
Refactoring a go projectRefactoring a go project
Refactoring a go project
 
Improving DroidBox
Improving DroidBoxImproving DroidBox
Improving DroidBox
 
Introduction to Dynamic Analysis of Android Application
Introduction to Dynamic Analysis of Android ApplicationIntroduction to Dynamic Analysis of Android Application
Introduction to Dynamic Analysis of Android Application
 
Understanding Java Dynamic Proxies
Understanding Java Dynamic ProxiesUnderstanding Java Dynamic Proxies
Understanding Java Dynamic Proxies
 
From zero to hero with React Native!
From zero to hero with React Native!From zero to hero with React Native!
From zero to hero with React Native!
 
JPA 스터디 Week2 - Object Relational Mapping
JPA 스터디 Week2 - Object Relational MappingJPA 스터디 Week2 - Object Relational Mapping
JPA 스터디 Week2 - Object Relational Mapping
 
Java notes | All Basics |
Java notes | All Basics |Java notes | All Basics |
Java notes | All Basics |
 
Java basic introduction
Java basic introductionJava basic introduction
Java basic introduction
 
Lombok
LombokLombok
Lombok
 
Type Annotations in Java 8
Type Annotations in Java 8 Type Annotations in Java 8
Type Annotations in Java 8
 
Project Lombok!
Project Lombok!Project Lombok!
Project Lombok!
 
JavaOne 2017 CON3276 - Selenium Testing Patterns Reloaded
JavaOne 2017 CON3276 - Selenium Testing Patterns ReloadedJavaOne 2017 CON3276 - Selenium Testing Patterns Reloaded
JavaOne 2017 CON3276 - Selenium Testing Patterns Reloaded
 
CDI In Real Life
CDI In Real LifeCDI In Real Life
CDI In Real Life
 

Andere mochten auch

2014.12.06 04 Евгений Тюменцев — Откуда появились s.o.l.i.d. принципы
2014.12.06 04 Евгений Тюменцев — Откуда появились s.o.l.i.d. принципы2014.12.06 04 Евгений Тюменцев — Откуда появились s.o.l.i.d. принципы
2014.12.06 04 Евгений Тюменцев — Откуда появились s.o.l.i.d. принципыHappyDev
 
iOS Zagreb Meetup #02 - Clean architecture in iOS apps (Leonard Beus @ Five)
iOS Zagreb Meetup #02 - Clean architecture in iOS apps (Leonard Beus @ Five)iOS Zagreb Meetup #02 - Clean architecture in iOS apps (Leonard Beus @ Five)
iOS Zagreb Meetup #02 - Clean architecture in iOS apps (Leonard Beus @ Five)Infinum
 
Jorge D. Ortiz Fuentes "Hands on Implementation of Clean Architecture for And...
Jorge D. Ortiz Fuentes "Hands on Implementation of Clean Architecture for And...Jorge D. Ortiz Fuentes "Hands on Implementation of Clean Architecture for And...
Jorge D. Ortiz Fuentes "Hands on Implementation of Clean Architecture for And...IT Event
 
Infinum iOS Talks #4 - Making our VIPER more reactive
Infinum iOS Talks #4 - Making our VIPER more reactiveInfinum iOS Talks #4 - Making our VIPER more reactive
Infinum iOS Talks #4 - Making our VIPER more reactiveInfinum
 
Choosing the architecture
Choosing the architectureChoosing the architecture
Choosing the architectureLucas Fonseca
 
Clean architecture workshop
Clean architecture workshopClean architecture workshop
Clean architecture workshopJorge Ortiz
 
Introduction to VIPER Architecture
Introduction to VIPER ArchitectureIntroduction to VIPER Architecture
Introduction to VIPER ArchitectureHendy Christianto
 
iOS viper presentation
iOS viper presentationiOS viper presentation
iOS viper presentationRajat Datta
 
Rambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и SwiftRambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и SwiftRAMBLER&Co
 
iOS Coding Best Practices
iOS Coding Best PracticesiOS Coding Best Practices
iOS Coding Best PracticesJean-Luc David
 

Andere mochten auch (13)

2014.12.06 04 Евгений Тюменцев — Откуда появились s.o.l.i.d. принципы
2014.12.06 04 Евгений Тюменцев — Откуда появились s.o.l.i.d. принципы2014.12.06 04 Евгений Тюменцев — Откуда появились s.o.l.i.d. принципы
2014.12.06 04 Евгений Тюменцев — Откуда появились s.o.l.i.d. принципы
 
"Clean" Architecture
"Clean" Architecture"Clean" Architecture
"Clean" Architecture
 
iOS Zagreb Meetup #02 - Clean architecture in iOS apps (Leonard Beus @ Five)
iOS Zagreb Meetup #02 - Clean architecture in iOS apps (Leonard Beus @ Five)iOS Zagreb Meetup #02 - Clean architecture in iOS apps (Leonard Beus @ Five)
iOS Zagreb Meetup #02 - Clean architecture in iOS apps (Leonard Beus @ Five)
 
Jorge D. Ortiz Fuentes "Hands on Implementation of Clean Architecture for And...
Jorge D. Ortiz Fuentes "Hands on Implementation of Clean Architecture for And...Jorge D. Ortiz Fuentes "Hands on Implementation of Clean Architecture for And...
Jorge D. Ortiz Fuentes "Hands on Implementation of Clean Architecture for And...
 
Infinum iOS Talks #4 - Making our VIPER more reactive
Infinum iOS Talks #4 - Making our VIPER more reactiveInfinum iOS Talks #4 - Making our VIPER more reactive
Infinum iOS Talks #4 - Making our VIPER more reactive
 
Choosing the architecture
Choosing the architectureChoosing the architecture
Choosing the architecture
 
Clean architecture workshop
Clean architecture workshopClean architecture workshop
Clean architecture workshop
 
Introduction to VIPER Architecture
Introduction to VIPER ArchitectureIntroduction to VIPER Architecture
Introduction to VIPER Architecture
 
From mvc to viper
From mvc to viperFrom mvc to viper
From mvc to viper
 
iOS viper presentation
iOS viper presentationiOS viper presentation
iOS viper presentation
 
VIPER - Design Pattern
VIPER - Design PatternVIPER - Design Pattern
VIPER - Design Pattern
 
Rambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и SwiftRambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и Swift
 
iOS Coding Best Practices
iOS Coding Best PracticesiOS Coding Best Practices
iOS Coding Best Practices
 

Ähnlich wie Why the Dark Side should use Swift and a SOLID Architecture

MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars
MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars
MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars PROIDEA
 
Escape from Mars
Escape from MarsEscape from Mars
Escape from MarsJorge Ortiz
 
Scaladroids: Developing Android Apps with Scala
Scaladroids: Developing Android Apps with ScalaScaladroids: Developing Android Apps with Scala
Scaladroids: Developing Android Apps with ScalaOstap Andrusiv
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Android development with Scala and SBT
Android development with Scala and SBTAndroid development with Scala and SBT
Android development with Scala and SBTAnton Yalyshev
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojureAbbas Raza
 
TDD and mobile development: some forgotten techniques, illustrated with Android
TDD and mobile development: some forgotten techniques, illustrated with AndroidTDD and mobile development: some forgotten techniques, illustrated with Android
TDD and mobile development: some forgotten techniques, illustrated with AndroidCodemotion
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important PartsSergey Bolshchikov
 
Play! Framework for JavaEE Developers
Play! Framework for JavaEE DevelopersPlay! Framework for JavaEE Developers
Play! Framework for JavaEE DevelopersTeng Shiu Huang
 
Dart structured web apps
Dart   structured web appsDart   structured web apps
Dart structured web appschrisbuckett
 
Dart, unicorns and rainbows
Dart, unicorns and rainbowsDart, unicorns and rainbows
Dart, unicorns and rainbowschrisbuckett
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js frameworkBen Lin
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahNick Plante
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummaryAmal Khailtash
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングscalaconfjp
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Ngoc Dao
 
Matteo Vaccari - TDD per Android | Codemotion Milan 2015
Matteo Vaccari - TDD per Android | Codemotion Milan 2015Matteo Vaccari - TDD per Android | Codemotion Milan 2015
Matteo Vaccari - TDD per Android | Codemotion Milan 2015Codemotion
 
JSAnkara Swift v React Native
JSAnkara Swift v React NativeJSAnkara Swift v React Native
JSAnkara Swift v React NativeMuhammed Demirci
 
Kotlin. One language to dominate them all.
Kotlin. One language to dominate them all.Kotlin. One language to dominate them all.
Kotlin. One language to dominate them all.Daniel Llanos Muñoz
 

Ähnlich wie Why the Dark Side should use Swift and a SOLID Architecture (20)

MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars
MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars
MCE^3 - Jorge D. Ortiz - Fuentes - Escape From Mars
 
Escape from Mars
Escape from MarsEscape from Mars
Escape from Mars
 
Scaladroids: Developing Android Apps with Scala
Scaladroids: Developing Android Apps with ScalaScaladroids: Developing Android Apps with Scala
Scaladroids: Developing Android Apps with Scala
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Android development with Scala and SBT
Android development with Scala and SBTAndroid development with Scala and SBT
Android development with Scala and SBT
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
 
TDD and mobile development: some forgotten techniques, illustrated with Android
TDD and mobile development: some forgotten techniques, illustrated with AndroidTDD and mobile development: some forgotten techniques, illustrated with Android
TDD and mobile development: some forgotten techniques, illustrated with Android
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important Parts
 
Play! Framework for JavaEE Developers
Play! Framework for JavaEE DevelopersPlay! Framework for JavaEE Developers
Play! Framework for JavaEE Developers
 
Dart structured web apps
Dart   structured web appsDart   structured web apps
Dart structured web apps
 
Dart, unicorns and rainbows
Dart, unicorns and rainbowsDart, unicorns and rainbows
Dart, unicorns and rainbows
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and Pindah
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
 
Matteo Vaccari - TDD per Android | Codemotion Milan 2015
Matteo Vaccari - TDD per Android | Codemotion Milan 2015Matteo Vaccari - TDD per Android | Codemotion Milan 2015
Matteo Vaccari - TDD per Android | Codemotion Milan 2015
 
Dart
DartDart
Dart
 
JSAnkara Swift v React Native
JSAnkara Swift v React NativeJSAnkara Swift v React Native
JSAnkara Swift v React Native
 
Kotlin. One language to dominate them all.
Kotlin. One language to dominate them all.Kotlin. One language to dominate them all.
Kotlin. One language to dominate them all.
 

Mehr von Jorge Ortiz

Tell Me Quando - Implementing Feature Flags
Tell Me Quando - Implementing Feature FlagsTell Me Quando - Implementing Feature Flags
Tell Me Quando - Implementing Feature FlagsJorge Ortiz
 
Unit Test your Views
Unit Test your ViewsUnit Test your Views
Unit Test your ViewsJorge Ortiz
 
Control your Voice like a Bene Gesserit
Control your Voice like a Bene GesseritControl your Voice like a Bene Gesserit
Control your Voice like a Bene GesseritJorge Ortiz
 
Kata gilded rose en Golang
Kata gilded rose en GolangKata gilded rose en Golang
Kata gilded rose en GolangJorge Ortiz
 
CYA: Cover Your App
CYA: Cover Your AppCYA: Cover Your App
CYA: Cover Your AppJorge Ortiz
 
Refactor your way forward
Refactor your way forwardRefactor your way forward
Refactor your way forwardJorge Ortiz
 
201710 Fly Me to the View - iOS Conf SG
201710 Fly Me to the View - iOS Conf SG201710 Fly Me to the View - iOS Conf SG
201710 Fly Me to the View - iOS Conf SGJorge Ortiz
 
Home Improvement: Architecture & Kotlin
Home Improvement: Architecture & KotlinHome Improvement: Architecture & Kotlin
Home Improvement: Architecture & KotlinJorge Ortiz
 
Architectural superpowers
Architectural superpowersArchitectural superpowers
Architectural superpowersJorge Ortiz
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive AppsJorge 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
 
Android clean architecture workshop 3h edition
Android clean architecture workshop 3h editionAndroid clean architecture workshop 3h edition
Android clean architecture workshop 3h editionJorge Ortiz
 
To Protect & To Serve
To Protect & To ServeTo Protect & To Serve
To Protect & To ServeJorge Ortiz
 
TDD for the masses
TDD for the massesTDD for the masses
TDD for the massesJorge Ortiz
 
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
 
Building for perfection
Building for perfectionBuilding for perfection
Building for perfectionJorge Ortiz
 
TDD by Controlling Dependencies
TDD by Controlling DependenciesTDD by Controlling Dependencies
TDD by Controlling DependenciesJorge 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
 
Core Data in Modern Times
Core Data in Modern TimesCore Data in Modern Times
Core Data in Modern TimesJorge Ortiz
 
Swift testing ftw
Swift testing ftwSwift testing ftw
Swift testing ftwJorge Ortiz
 

Mehr von Jorge Ortiz (20)

Tell Me Quando - Implementing Feature Flags
Tell Me Quando - Implementing Feature FlagsTell Me Quando - Implementing Feature Flags
Tell Me Quando - Implementing Feature Flags
 
Unit Test your Views
Unit Test your ViewsUnit Test your Views
Unit Test your Views
 
Control your Voice like a Bene Gesserit
Control your Voice like a Bene GesseritControl your Voice like a Bene Gesserit
Control your Voice like a Bene Gesserit
 
Kata gilded rose en Golang
Kata gilded rose en GolangKata gilded rose en Golang
Kata gilded rose en Golang
 
CYA: Cover Your App
CYA: Cover Your AppCYA: Cover Your App
CYA: Cover Your App
 
Refactor your way forward
Refactor your way forwardRefactor your way forward
Refactor your way forward
 
201710 Fly Me to the View - iOS Conf SG
201710 Fly Me to the View - iOS Conf SG201710 Fly Me to the View - iOS Conf SG
201710 Fly Me to the View - iOS Conf SG
 
Home Improvement: Architecture & Kotlin
Home Improvement: Architecture & KotlinHome Improvement: Architecture & Kotlin
Home Improvement: Architecture & Kotlin
 
Architectural superpowers
Architectural superpowersArchitectural superpowers
Architectural superpowers
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive Apps
 
iOS advanced architecture workshop 3h edition
iOS advanced architecture workshop 3h editioniOS advanced architecture workshop 3h edition
iOS advanced architecture workshop 3h edition
 
Android clean architecture workshop 3h edition
Android clean architecture workshop 3h editionAndroid clean architecture workshop 3h edition
Android clean architecture workshop 3h edition
 
To Protect & To Serve
To Protect & To ServeTo Protect & To Serve
To Protect & To Serve
 
TDD for the masses
TDD for the massesTDD for the masses
TDD for the masses
 
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
 
Building for perfection
Building for perfectionBuilding for perfection
Building for perfection
 
TDD by Controlling Dependencies
TDD by Controlling DependenciesTDD by Controlling Dependencies
TDD by Controlling Dependencies
 
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
 
Core Data in Modern Times
Core Data in Modern TimesCore Data in Modern Times
Core Data in Modern Times
 
Swift testing ftw
Swift testing ftwSwift testing ftw
Swift testing ftw
 

Kürzlich hochgeladen

%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benonimasabamasaba
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...masabamasaba
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in sowetomasabamasaba
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...masabamasaba
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburgmasabamasaba
 

Kürzlich hochgeladen (20)

%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 

Why the Dark Side should use Swift and a SOLID Architecture

  • 1. Why the Dark Side should use Swift and a SOLID Architecture Jorge D. Ortiz-Fuentes @jdortiz #SwiftDarkSide
  • 3. #SwiftDarkSide Agenda The Weaknesses of the Dark Side SOLID Architecture Design patterns
  • 13. #SwiftDarkSide Needs to Address Fast growth Robustness • testable • decoupled • debuggable (blame) Team collaboration Reusable Defer decisions Replaceable frameworks
  • 14. There is a way: SOLID Principles
  • 16. I find your lack of faith disturbing
  • 18. Clean Architecture AppDelegate View (VC) Presenter Interactor Entity Gateway Connector
  • 19. #SwiftDarkSide Single Responsibility MVC is not enough More classes, but more cohesive: only one reason to change
  • 20. #SwiftDarkSide Business Logic import Foundation class ShowAllSpeakersInteractor { // MARK: - Properties let entityGateway: EntityGatewayFetchSpeakersProtocol weak var presenter: SpeakersListPresenterProtocol? // MARK: - Initializers init(entityGateway: EntityGatewayFetchSpeakersProtocol) { self.entityGateway = entityGateway } } extension ShowAllSpeakersInteractor: InteractorCommandProtocol { func execute() { let entities = entityGateway.fetchAllSpeakers() let displayData = entities.map({entity in return SpeakerDisplayData(speaker: entity)}) presenter?.presentAllSpeakers(displayData) } }
  • 21. #SwiftDarkSide Open Close Open to Extension, Closed to Modification
  • 22. #SwiftDarkSide class SpeakersTableViewController: UITableViewController, SegueHandlerTypeProtocol { static let speakerCellIdentifier = "SpeakerCell" var eventHandler: SpeakersListEventHandlerProtocol? var numberOfRows = 0 override func viewDidLoad() { super.viewDidLoad() eventHandler?.viewDidLoad() } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return numberOfRows } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier(SpeakersTa bleViewController.speakerCellIdentifier, forIndexPath: indexPath) as! SpeakerTableViewCell eventHandler?.presentCell(cell, indexPath: indexPath) return cell } } extension SpeakersTableViewController: SpeakersListViewProtocol { func configureListWithNumberOfRows(numberOfRows : Int) { self.numberOfRows = numberOfRows } func addRowsAtIndexPaths(indexPaths: [NSIndexPath]) { self.tableView.insertRowsAtIndexPaths(inde xPaths, withRowAnimation: UITableViewRowAnimation.Automatic) } } Passive View
  • 23. #SwiftDarkSide Liskov Substitution It should be possible to use derived classes without special care
  • 24. #SwiftDarkSide extension SpeakersListsPresenter: SpeakersListEventHandlerProtocol { func viewDidLoad() { interactor.execute() } func presentCell(cell: SpeakerCellProtocol, indexPath: NSIndexPath) { let index = indexPath.row guard index < speakers.count else { return } let speaker = speakers[index] cell.displayName(speaker.name) cell.displayTitle(speaker.title) cell.displayDateSubmitted(relativeDateStrin gFromDate(speaker.dateSubmitted)) } } Presentation class SpeakersListsPresenter { weak var view: SpeakersListViewProtocol? let interactor: ShowAllSpeakersInteractor private var speakers: [SpeakerDisplayData]=[] // MARK: - Initializer init(interactor: ShowAllSpeakersInteractor, deleteInteractor: DeleteSpeakerInteractorProtocol) { self.interactor = interactor } } extension SpeakersListsPresenter: SpeakersListPresenterProtocol { func presentAllSpeakers(speakers: [SpeakerDisplayData]) { view?.configureListWithNumberOfRows(speakers.count) self.speakers = speakers let addedIndexPaths = speakers.enumerate() .map({(index, _) in return NSIndexPath(forRow: index, inSection: 0)}) view?.addRowsAtIndexPaths(addedIndexPaths) } }
  • 25. #SwiftDarkSide Interface Segregation Don’t force a class to depend on methods that it won’t use One interactor will not likely use every functionality of the entity gateway
  • 26. #SwiftDarkSide class InMemorySpeakersRepo { // MARK: - Properties var speakers: [Speaker] = [] init() { } } extension InMemorySpeakersRepo: EntityGatewayFetchSpeakersProtocol { func fetchAllSpeakers() -> [Speaker] { return speakers } } extension InMemorySpeakersRepo: EntityGatewayCreateSpeakerProtocol { func createSpeaker(name name: String, title: String, synopsis: String, dateSubmitted: NSDate) { let id = IdentityGenerator.newUUID() speakers.append(Speaker(id: id, name: name, title: title, synopsis: synopsis, dateSubmitted: dateSubmitted)) } } extension InMemorySpeakersRepo: EntityGatewayDeleteSpeakerProtocol { func deleteSpeaker(id: String) { speakers = speakers.filter { speaker in speaker.id != id } } } Different Functions of the Entity Gateway
  • 27. #SwiftDarkSide Dependency Inversion The business case SHOULDN’T depend on the frameworks
  • 28. #SwiftDarkSide Deletion Use Case class DeleteSpeakerInteractor { let entityGateway: EntityGatewayDeleteSpeakerProtocol var id: String? init(entityGateway: EntityGatewayDeleteSpeakerProtocol) { self.entityGateway = entityGateway } } extension DeleteSpeakerInteractor : InteractorCommandProtocol { func execute() { guard let id = self.id else { return } entityGateway.deleteSpeaker(id) } }
  • 30. Take me Outta Here func presentCell(cell: SpeakerCellProtocol, indexPath: NSIndexPath) { let index = indexPath.row guard index < speakers.count else { return } let speaker = speakers[index] cell.displayName(speaker.name) cell.displayTitle(speaker.title) cell.displayDateSubmitted(relativeDateStringFromDate(s peaker.dateSubmitted)) } Know That!
  • 31. var control = Houston(fuel: 1.0, astronaut: nil, spaceshipOK: true) do { try control.launchSpaceship() } catch Houston.LaunchError.NoFuel { // Add Fuel print("Adding fuel") } catch Houston.LaunchError.NoAstronaut { print("Next in line") } catch Houston.LaunchError.BrokenShip(let problem) { print(problem) } catch let unknowError { // } Ready for Life class Houston { let fuel: Double let astronaut: String let spaceshipOK: Bool init (fuel: Double, astronaut: String?, spaceshipOK: Bool) { self.fuel = fuel self.astronaut = astronaut ?? "" self.spaceshipOK = spaceshipOK } enum LaunchError: ErrorType { case NoFuel, NoAstronaut, BrokenShip(String) } func launchSpaceship() throws { guard fuel >= 1.0 else { throw LaunchError.NoFuel } guard astronaut != "" else { throw LaunchError.NoAstronaut } guard spaceshipOK else { throw LaunchError.BrokenShip("Engine") } print("Launching spaceship") } } Know That!
  • 32. class Text { func displayContents() { print("Hola") } } class NullText: Text { override func displayContents() { print(“Not much here") } } func fetchText() -> Text { return NullText() } let text = fetchText() text.displayContents() Null Object class Text { func displayContents() { print("Hola") } } func fetchText() -> Text? { return nil } if let text = fetchText() { text.displayContents() }
  • 33. Poor Template class PoorTrooper { func getIntoSpaceShip() { print("Commencing countdown engines on") } func conquer(target: String) { fatalError() } func comeBack() { print("Planet earth is blue") } func attack(target: String) { getIntoSpaceShip() conquer(target) comeBack() } } let cloneTrooper = PoorTrooper() cloneTrooper.attack("Alderaan")
  • 34. Swifty Template protocol Trooper { func getIntoSpaceShip() func conquer(target: String) func comeBack() func attack(target: String) } extension Trooper { func getIntoSpaceShip() { print("Commencing countdown engines on") } func comeBack() { print("Planet earth is blue") } func attack(target: String) { getIntoSpaceShip() conquer(target) comeBack() } } class StormTrooper: Trooper { func conquer(target: String) { print("Become part of the Empire, (target)") } } let finn = StormTrooper() finn.attack("Tatooine")
  • 36. #SwiftDarkSide Recommendations Pay attention to your architecture; It always pays off Use Principles to take decisions Take advantage of the language and adapt the patterns to it In case of doubt, ask for an architecture loan and ship it