Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Setting Boundaries
Search
Francisco Díaz
March 10, 2016
Programming
190
1
Share
Setting Boundaries
Presented at ViDIA meetup.
Francisco Díaz
March 10, 2016
More Decks by Francisco Díaz
See All by Francisco Díaz
Inteligencia Artificial en PedidosYa - Una mirada pragmática
fdiaz
0
30
Working effectively at scale
fdiaz
4
320
I hate public speaking. So why do I keep doing it?
fdiaz
0
160
Definiendo límites
fdiaz
1
150
Si odio hablar en público. ¿Por qué lo sigo haciendo?
fdiaz
2
170
Move fast and keep your code quality
fdiaz
1
420
De qué hablo cuando hablo de trabajo remoto
fdiaz
1
180
Swift Values
fdiaz
0
170
Sisifo o Cómo empezar de nuevo - y otra vez.
fdiaz
0
160
Other Decks in Programming
See All in Programming
Lemonade + Foundry Toolkit でお手軽アプリ開発
seosoft
1
210
運用エージェントは "作る" から "育てる" へ - 記憶と自己進化の3層設計パターン / self-evolving-agents-three-layer-agent-design
gawa
12
3.2k
ふつうのFeature Flag実践入門
irof
7
3.3k
さぁV100、メモリをお食べ・・・
nilpe
0
110
oxlintはeslint/typescript-eslintを置き換えられるのか
shomafujita
2
280
横断組織出身のQAEがインプロセスQAEでつまずいたこと・活かせたこと
ty89
0
440
CSC307 Lecture 17
javiergs
PRO
0
260
開発体験を左右するライブラリの API 設計 - GraphQL スキーマ構築ライブラリから考える #tskaigi
izumin5210
2
1.2k
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
1.5k
Talking to terminals (and how they talk back) (KotlinConf 2026)
jakewharton
PRO
1
160
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
460
密結合なバックエンドから TypeScript のコードを生成する
kemuridama
1
390
Featured
See All Featured
The SEO identity crisis: Don't let AI make you average
varn
0
480
Information Architects: The Missing Link in Design Systems
soysaucechin
0
940
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
210
Context Engineering - Making Every Token Count
addyosmani
9
920
How GitHub (no longer) Works
holman
316
150k
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
A Soul's Torment
seathinner
6
2.8k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.2k
Bash Introduction
62gerente
615
210k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Prompt Engineering for Job Search
mfonobong
0
320
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
310
Transcript
Setting Boundaries
None
Francisco Díaz @fco_diaz
3 iOS Devs 28 hours 1 project == Merge Conflicts
What do we want? → Minimize duplication of code. →
Develop independently without stepping on each other's toes.
Feature verticals: → Big Panic button → Today widget →
Knock
Big Panic button:
What needs to be done? → Create the button. →
We need a way to create reports. → Make a backend call to save this information.
Today widget:
What needs to be done? → Create the extension button.
→ We need a way to create reports. → Make a backend call to save this information.
What was it that we wanted? → Minimize duplication of
code. → Develop independently without stepping on each other's toes.
None
Let's try again!
→ Create the button. → We need a way to
create reports. → Make a backend call to save this information.
UI / Presentation Create the button.
Business logic We need a way to create reports.
Backend connection Make a backend call to save this information.
None
To recap: → Minimize duplication of code. → Develop independently
without stepping on each other's toes.
We can solve any problem by introducing an extra level
of indirection — David Wheeler
Dependency inversion
struct ModelDataManager { let APIClient: APIType init(APIClient: APIType) { self.APIClient
= APIClient } }
protocol APIType { func createReport(completion: JSONDictionary? -> Void) } struct
API { private let manager: Alamofire.Manager init() { manager = Alamofire.Manager() } } extension API: APIType { func createReport(completion: JSONDictionary? -> Void) { manager.request(.POST, "https://some.com/api/report") .responseJSON { response in completion(response) } } }
struct ModelDataManager { let APIClient: APIType init(API: APIType) { self.APIClient
= API } static func defaultManager() -> ModelDataManager { let APIClient = API() return ModelDataManager(API: APIClient) } func createReport(completionHandler completion: Report? -> Void) { APIClient.createReport() { jsonDictionary in let report = ... // Parse jsonDictionary into Report completion(report) } } }
Benefits → Testable. → Decoupled. → Easy to fake our
networking layer.
None
struct FakeAPI: APIType { func createReport(completion: JSONDictionary? -> Void) {
let dictionary = ["id": 12345] completion(dictionary) } }
struct ModelDataManager { let APIClient: APIType init(API: APIType) { self.APIClient
= API } static func defaultManager() -> ModelDataManager { // let APIClient = API() let APIClient = FakeAPI() return ModelDataManager(API: APIClient) } }
Questions? Slides are available at: https://github.com/fdiaz/settings-boundaries-talk References: Architecture: The Lost
Years The Clean Architecture