SlideShare a Scribd company logo
Refactor Your
Way Forward
Jorge D. Ortiz-Fuentes
@jdortiz
A Canonical

Examples

Production
#AdvArchMobile
Agenda
★ The challenge
★ Strategy
★ Tactics
★ Recap
The
Challenge
#AdvArchMobile
Sounds familiar?
★ Legacy application
• No tests
• Outdated
★ Written in Objective-C
★ Not (m)any tests
★ Multiple styles and ways to do things
★ Not much info from the previous developer
#AdvArchMobile
Need a Better
Architecture
★ Difficult to add new features without
breaking existing ones
★ Difficult to find and solve bugs
★ Expensive to maintain
★ Difficult to add tests
#AdvArchMobile
My Example
★ App: OpenIt
★ Credit: Patrick Balestra
★ Thanks!
★ Great code for an example
★ All criticism IS constructive
Strategy
Ideas to Enhance
Persistance FW
View
Network
LocationFW
Presenter
Entity Gateway
Clean Architecture
Interactor
Entity
Clean Architecture: iOS
App
Delegate
View (VC) Presenter Interactor
Entity
Gateway
Connector
#AdvArchMobile
Goals
★ New feature: Apple rating API
★ Don’t break anything
★ Enhance when possible
No Big Bang Rewrite
Still love the TV series
Information
Gathering
– Sun Tzu
“Know your enemy and know yourself and
you can fight a hundred battles without
disaster.”
Pragmatic Information
Gathering
Make it Work
#AdvArchMobile
Make it Work
★ Install dependencies
• Pods/Carthage, if any
• API keys
★ Build
★ Fix big problems until it works
#AdvArchMobile
Make it Work
★ DON’T update the project settings yet
★ DON’T add any functionality yet
★ DON’T fix any other bugs yet
Commit!
#AdvArchMobile
Explore the Battlefield
★ Take a glimpse a the code
★ Tests? Runnable? Pass?
★ Documentation?
★ Oral transmission?
★ Business goals
#AdvArchMobile
Design your strategy
★ Planed features
★ Pain points
#AdvArchMobile
Main Strategic
Approaches
★ From the model upwards
• Less intuitive
• Still requires injections from top to bottom
★ From the views inwards
• More work initially
#AdvArchMobile
Shape the Strategy
★ App delegate: Size? Relevant tasks? Easy to
replace (And remove main.m)?
★ Storyboards?
★ Tests coverage? Only for the model?
★ Frameworks used (Persistence & others)?
★ DI? Abstractions for DIP?
★ VCs screaming for changes?
But remember
Only small non breaking changes allowed
Tactics
Add Tests
#AdvArchMobile
Add Tests
★ Set up the testing target
★ Language is Swift
★ Start with main target
★ Don't add others (frameworks) until required
★ Cmd+U To test that it works.
★ Delete the default tests
Commit!
Zero Visibility
Here Be Dragons
Use the Tools
#AdvArchMobile
Proper Git
★ Branch often
★ Better, git flow: Feature branch for each
part of migration
★ Avoid long lived branches
★ Use branch by abstraction instead
#AdvArchMobile
Branch by Abstraction
2 1
1
1 2
#AdvArchMobile
Use Xcode Groups
★ Put all legacy code in a group
★ Support files and assets in another one
★ Create new Groups (or folders) to organize
new code
Use Xcode Refactor
Feature
😂
Replace App
Delegate (& main.m)
#AdvArchMobile
Very Simple (when it is)
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
}
Commit!
Enable Dependency
Injection
#AdvArchMobile
Introduce DI
from Root VC
★ Change behavior in Info.plist
★ App delegate creates initial view controller
★ Pass into a dumb (yet) connector
★ Add Bridging header
#AdvArchMobile
Info.plist
Commit!
View Controller Talks
to Dumb Presenter
Mark Connection Points
#AdvArchMobile
Introduce Presenter
★ @objc
★ Pass events
★ Test VC
★ Generate a skeleton for the presenter
#AdvArchMobile
Cheat to keep it working
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
// DONE: Invoke presenter numberOfActions
NSInteger rows = self.presenter.numberOfActions;
// TODO: Remove when using real presenter
if (rows < 0) {
rows = self.actions.count;
}
return rows;
}
#AdvArchMobile
Cheat to provide
dependencies
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// DONE: Invoke presenter configure(cell:forRow:)
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
// TODO: In the new view replace with the actual cell
[self.presenter configureWithCell:[[ActionTableViewCell alloc]
init] atRow:indexPath.row];
cell.textLabel.text = self.actions[indexPath.row][0][@"Title"];
cell.detailTextLabel.text = self.actions[indexPath.row][1]
[@"Type"];
cell.imageView.image = [UIImage
imageNamed:self.actions[indexPath.row][1][@"Type"]];
return cell;
}
Commit!
Refactor Persistence
#AdvArchMobile
- (void)viewDidLoad {
[super viewDidLoad];
[self.presenter viewReady];
// …
self.actions = [self
fetchActions];
// …
}
- (NSMutableArray *) fetchActions
{
return [[NSMutableArray alloc]
initWithArray:[[NSUserDefaults
standardUserDefaults]
objectForKey:@"actions"]];
}
Extract Methods with
Persistence
- (void)viewDidLoad {
[super viewDidLoad];
[self.presenter
viewReady];
// …
self.actions =
[[NSMutableArray alloc]
initWithArray:
[[NSUserDefaults
standardUserDefaults]
objectForKey:@"actions"]];
// …
}
#AdvArchMobile
And Test It
func testFetchActionsObtainsDataFromUserDefaults() {
let userDefaultsMock = UserDefaultsMock()
sut.setValue(userDefaultsMock, forKey: "userDefaults")
_ = sut.fetchActions()
XCTAssertTrue(userDefaultsMock.objectForKeyInvoked)
}
Commit!
Get the new VC in
#AdvArchMobile
New Swift VC
★ Replaces the old one
★ Refactor Storyboard
★ New Swift class with the desired name
★ Reuse the tests to create an instance of this
one
Refactor the Storyboard
Deal with
Limitations
#AdvArchMobile
Rough Edges
★ Structs & Enums
★ Tuples
★ Generics
★ Curried & global functions
★ Typealiases
#AdvArchMobile
@objcMembers class ActionWrapper: NSObject
{
private var action: Action
var title: String {
get {
return action.title
}
set(newTitle) {
action.title = newTitle
}
}
//…
init(action: Action) {
self.action = action
}
init(title: String, type: String, url:
String) {
action = Action(title: title,
type: type, url: url)
}
}
Use Wrappers
struct Action {
var title: String
var type: String
var url: String
}
Commit!
#AdvArchMobile
But…
★ Entity Gateway should implement both
★ Value semantics are lost
★ Use scarcely
★ Remove when possible
And Finally…
New Use Case
#AdvArchMobile
Use Case
typealias AskForRatingCompletion = (Bool) -> ()
class AskForRatingUseCase: UseCase {
let entityGateway: EntityGateway
let preferencesGateway: PreferencesGateway
let completion: AskForRatingCompletion
init(entityGateway: EntityGateway, preferencesGateway:
PreferencesGateway,
completion: @escaping AskForRatingCompletion) {
self.entityGateway = entityGateway
self.preferencesGateway = preferencesGateway
self.completion = completion
}
func execute() {
let ask = entityGateway.numberOfActions > 10
&& preferencesGateway.daysSinceLastRating > 180
completion(ask)
}
}
#AdvArchMobile
// View (extension)
func askForRating() {
SKStoreReviewController.requestRe
view()
}
Presenter & View
// Presenter
func viewReady() {
actions = fetchActions()
mayAskUserForRating()
}
private func
mayAskUserForRating() {
let useCase =
useCaseFactory.askForRatingUseCas
e(completion: { (shouldAsk: Bool)
in
view.askForRating()
})
useCase.execute()
}
Commit!
Recap
#AdvArchMobile
Recap
★ Incremental refactoring is feasible
★ Design your strategy
★ Use the tactics
★ Small non breaking changes are best
★ Tests are key
★ Don’t follow sequential order
Tusen
Takk!
Thank
You!
@jdortiz
#AdvArchMobile

More Related Content

PPTX
Javascript unit tests with angular 1.x
Ron Apelbaum
 
PDF
Angular testing
Yu Jin
 
PDF
Automated Testing in Angular Slides
Jim Lynch
 
PDF
Polyglot automation - QA Fest - 2015
Iakiv Kramarenko
 
PDF
Drupal and testing (2010 - 2011 / 2)
Peter Arato
 
PDF
Angular Application Testing
Troy Miles
 
PDF
TypeScript for Java Developers
Yakov Fain
 
PDF
Using JHipster for generating Angular/Spring Boot apps
Yakov Fain
 
Javascript unit tests with angular 1.x
Ron Apelbaum
 
Angular testing
Yu Jin
 
Automated Testing in Angular Slides
Jim Lynch
 
Polyglot automation - QA Fest - 2015
Iakiv Kramarenko
 
Drupal and testing (2010 - 2011 / 2)
Peter Arato
 
Angular Application Testing
Troy Miles
 
TypeScript for Java Developers
Yakov Fain
 
Using JHipster for generating Angular/Spring Boot apps
Yakov Fain
 

What's hot (20)

PPTX
Selenium In The Real World
iainrose
 
PPTX
Roslyn
Tomas Jansson
 
PDF
Variables in Pharo5
Marcus Denker
 
PDF
CocoaConf DC - Automate with Swift - Tony Ingraldi
Tony Ingraldi
 
PPTX
Javascript omg!
bwullems
 
PDF
Wuff: Building Eclipse Applications and Plugins with Gradle
Andrey Hihlovsky
 
PDF
Ebay legacy-code-retreat
Konrad Malawski
 
PDF
El viaje de Angular1 a Angular2
Antonio de la Torre Fernández
 
PDF
ClassJS
Michael Barrett
 
PDF
Gtg12
Poga Po
 
PPTX
Why I don’t want to develop iOS apps in Objective C
SeniorDevOnly
 
PDF
Using JHipster for generating Angular/Spring Boot apps
Yakov Fain
 
PDF
Intro to JavaScript
Yakov Fain
 
PDF
Java Intro: Unit1. Hello World
Yakov Fain
 
PDF
Angular 2 Essential Training
Patrick Schroeder
 
PDF
Apigility introduction v2 (glasgow php)
Engineor
 
PDF
PuppetConf 2016 Moving from Exec to Types and Provides
Martin Alfke
 
PDF
Behave manners for ui testing pycon2019
Panos Christeas
 
PDF
Unit Testing JavaScript Applications
Ynon Perek
 
PDF
Type script for_java_dev_jul_2020
Yakov Fain
 
Selenium In The Real World
iainrose
 
Variables in Pharo5
Marcus Denker
 
CocoaConf DC - Automate with Swift - Tony Ingraldi
Tony Ingraldi
 
Javascript omg!
bwullems
 
Wuff: Building Eclipse Applications and Plugins with Gradle
Andrey Hihlovsky
 
Ebay legacy-code-retreat
Konrad Malawski
 
El viaje de Angular1 a Angular2
Antonio de la Torre Fernández
 
Gtg12
Poga Po
 
Why I don’t want to develop iOS apps in Objective C
SeniorDevOnly
 
Using JHipster for generating Angular/Spring Boot apps
Yakov Fain
 
Intro to JavaScript
Yakov Fain
 
Java Intro: Unit1. Hello World
Yakov Fain
 
Angular 2 Essential Training
Patrick Schroeder
 
Apigility introduction v2 (glasgow php)
Engineor
 
PuppetConf 2016 Moving from Exec to Types and Provides
Martin Alfke
 
Behave manners for ui testing pycon2019
Panos Christeas
 
Unit Testing JavaScript Applications
Ynon Perek
 
Type script for_java_dev_jul_2020
Yakov Fain
 
Ad

Similar to Refactor your way forward (20)

PDF
Test Driven Development with JavaFX
Hendrik Ebbers
 
KEY
Rubymotion talk
pinfieldharm
 
PPTX
Unit testing on mobile apps
Buşra Deniz, CSM
 
PDF
Objective-C Is Not Java
Chris Adamson
 
PPTX
Exploring the power of Gradle in android studio - Basics & Beyond
Kaushal Dhruw
 
PDF
iOS for Android Developers (with Swift)
David Truxall
 
PDF
Titanium Alloy Tutorial
Fokke Zandbergen
 
PPTX
React nativebeginner1
Oswald Campesato
 
PDF
MFF UK - Introduction to iOS
Petr Dvorak
 
PPTX
Dependency Injection and Autofac
meghantaylor
 
PDF
Data Migrations in the App Engine Datastore
Ryan Morlok
 
ODP
2014 11 20 Drupal 7 -> 8 test migratie
hcderaad
 
PDF
Hotfixing iOS apps with Javascript
Sergio Padrino Recio
 
PDF
Swift testing ftw
Jorge Ortiz
 
PPTX
Angular4 kickstart
Foyzul Karim
 
PDF
Twins: OOP and FP
RichardWarburton
 
PDF
L04 Software Design Examples
Ólafur Andri Ragnarsson
 
PPTX
Setting Up CircleCI Workflows for Your Salesforce Apps
Daniel Stange
 
PDF
Eclipse 40 - Eclipse Summit Europe 2010
Lars Vogel
 
PDF
Session 3 - Object oriented programming with Objective-C (part 1)
Vu Tran Lam
 
Test Driven Development with JavaFX
Hendrik Ebbers
 
Rubymotion talk
pinfieldharm
 
Unit testing on mobile apps
Buşra Deniz, CSM
 
Objective-C Is Not Java
Chris Adamson
 
Exploring the power of Gradle in android studio - Basics & Beyond
Kaushal Dhruw
 
iOS for Android Developers (with Swift)
David Truxall
 
Titanium Alloy Tutorial
Fokke Zandbergen
 
React nativebeginner1
Oswald Campesato
 
MFF UK - Introduction to iOS
Petr Dvorak
 
Dependency Injection and Autofac
meghantaylor
 
Data Migrations in the App Engine Datastore
Ryan Morlok
 
2014 11 20 Drupal 7 -> 8 test migratie
hcderaad
 
Hotfixing iOS apps with Javascript
Sergio Padrino Recio
 
Swift testing ftw
Jorge Ortiz
 
Angular4 kickstart
Foyzul Karim
 
Twins: OOP and FP
RichardWarburton
 
L04 Software Design Examples
Ólafur Andri Ragnarsson
 
Setting Up CircleCI Workflows for Your Salesforce Apps
Daniel Stange
 
Eclipse 40 - Eclipse Summit Europe 2010
Lars Vogel
 
Session 3 - Object oriented programming with Objective-C (part 1)
Vu Tran Lam
 
Ad

More from Jorge Ortiz (20)

PDF
Tell Me Quando - Implementing Feature Flags
Jorge Ortiz
 
PDF
Unit Test your Views
Jorge Ortiz
 
PDF
Control your Voice like a Bene Gesserit
Jorge Ortiz
 
PDF
Kata gilded rose en Golang
Jorge Ortiz
 
PDF
CYA: Cover Your App
Jorge Ortiz
 
PDF
201710 Fly Me to the View - iOS Conf SG
Jorge Ortiz
 
PDF
Home Improvement: Architecture & Kotlin
Jorge Ortiz
 
PDF
Architectural superpowers
Jorge Ortiz
 
PDF
Architecting Alive Apps
Jorge Ortiz
 
PDF
iOS advanced architecture workshop 3h edition
Jorge Ortiz
 
PDF
Android clean architecture workshop 3h edition
Jorge Ortiz
 
PDF
To Protect & To Serve
Jorge Ortiz
 
PDF
Clean architecture workshop
Jorge Ortiz
 
PDF
Escape from Mars
Jorge Ortiz
 
PDF
Why the Dark Side should use Swift and a SOLID Architecture
Jorge Ortiz
 
PDF
Dependence day insurgence
Jorge Ortiz
 
PDF
Architectural superpowers
Jorge Ortiz
 
PDF
TDD for the masses
Jorge Ortiz
 
PDF
7 Stages of Unit Testing in iOS
Jorge Ortiz
 
PDF
Building for perfection
Jorge Ortiz
 
Tell Me Quando - Implementing Feature Flags
Jorge Ortiz
 
Unit Test your Views
Jorge Ortiz
 
Control your Voice like a Bene Gesserit
Jorge Ortiz
 
Kata gilded rose en Golang
Jorge Ortiz
 
CYA: Cover Your App
Jorge Ortiz
 
201710 Fly Me to the View - iOS Conf SG
Jorge Ortiz
 
Home Improvement: Architecture & Kotlin
Jorge Ortiz
 
Architectural superpowers
Jorge Ortiz
 
Architecting Alive Apps
Jorge Ortiz
 
iOS advanced architecture workshop 3h edition
Jorge Ortiz
 
Android clean architecture workshop 3h edition
Jorge Ortiz
 
To Protect & To Serve
Jorge Ortiz
 
Clean architecture workshop
Jorge Ortiz
 
Escape from Mars
Jorge Ortiz
 
Why the Dark Side should use Swift and a SOLID Architecture
Jorge Ortiz
 
Dependence day insurgence
Jorge Ortiz
 
Architectural superpowers
Jorge Ortiz
 
TDD for the masses
Jorge Ortiz
 
7 Stages of Unit Testing in iOS
Jorge Ortiz
 
Building for perfection
Jorge Ortiz
 

Recently uploaded (20)

DOCX
Can You Build Dashboards Using Open Source Visualization Tool.docx
Varsha Nayak
 
PPTX
Role Of Python In Programing Language.pptx
jaykoshti048
 
PDF
Generating Union types w/ Static Analysis
K. Matthew Dupree
 
PPTX
The-Dawn-of-AI-Reshaping-Our-World.pptxx
parthbhanushali307
 
PDF
10 posting ideas for community engagement with AI prompts
Pankaj Taneja
 
PDF
Applitools Platform Pulse: What's New and What's Coming - July 2025
Applitools
 
PDF
Bandai Playdia The Book - David Glotz
BluePanther6
 
PPT
Why Reliable Server Maintenance Service in New York is Crucial for Your Business
Sam Vohra
 
PPTX
Presentation about variables and constant.pptx
safalsingh810
 
PDF
Balancing Resource Capacity and Workloads with OnePlan – Avoid Overloading Te...
OnePlan Solutions
 
PDF
Using licensed Data Loss Prevention (DLP) as a strategic proactive data secur...
Q-Advise
 
PPTX
Maximizing Revenue with Marketo Measure: A Deep Dive into Multi-Touch Attribu...
bbedford2
 
PPTX
Presentation about Database and Database Administrator
abhishekchauhan86963
 
PDF
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
PDF
New Download MiniTool Partition Wizard Crack Latest Version 2025
imang66g
 
PDF
Exploring AI Agents in Process Industries
amoreira6
 
PPTX
slidesgo-unlocking-the-code-the-dynamic-dance-of-variables-and-constants-2024...
kr2589474
 
PPTX
TRAVEL APIs | WHITE LABEL TRAVEL API | TOP TRAVEL APIs
philipnathen82
 
PDF
Adobe Illustrator Crack Full Download (Latest Version 2025) Pre-Activated
imang66g
 
PDF
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
Can You Build Dashboards Using Open Source Visualization Tool.docx
Varsha Nayak
 
Role Of Python In Programing Language.pptx
jaykoshti048
 
Generating Union types w/ Static Analysis
K. Matthew Dupree
 
The-Dawn-of-AI-Reshaping-Our-World.pptxx
parthbhanushali307
 
10 posting ideas for community engagement with AI prompts
Pankaj Taneja
 
Applitools Platform Pulse: What's New and What's Coming - July 2025
Applitools
 
Bandai Playdia The Book - David Glotz
BluePanther6
 
Why Reliable Server Maintenance Service in New York is Crucial for Your Business
Sam Vohra
 
Presentation about variables and constant.pptx
safalsingh810
 
Balancing Resource Capacity and Workloads with OnePlan – Avoid Overloading Te...
OnePlan Solutions
 
Using licensed Data Loss Prevention (DLP) as a strategic proactive data secur...
Q-Advise
 
Maximizing Revenue with Marketo Measure: A Deep Dive into Multi-Touch Attribu...
bbedford2
 
Presentation about Database and Database Administrator
abhishekchauhan86963
 
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
New Download MiniTool Partition Wizard Crack Latest Version 2025
imang66g
 
Exploring AI Agents in Process Industries
amoreira6
 
slidesgo-unlocking-the-code-the-dynamic-dance-of-variables-and-constants-2024...
kr2589474
 
TRAVEL APIs | WHITE LABEL TRAVEL API | TOP TRAVEL APIs
philipnathen82
 
Adobe Illustrator Crack Full Download (Latest Version 2025) Pre-Activated
imang66g
 
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 

Refactor your way forward