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
1
140
Setting Boundaries
Presented at ViDIA meetup.
Francisco Díaz
March 10, 2016
Tweet
Share
More Decks by Francisco Díaz
See All by Francisco Díaz
Working effectively at scale
fdiaz
4
290
I hate public speaking. So why do I keep doing it?
fdiaz
0
130
Definiendo límites
fdiaz
1
110
Si odio hablar en público. ¿Por qué lo sigo haciendo?
fdiaz
2
130
Move fast and keep your code quality
fdiaz
1
360
De qué hablo cuando hablo de trabajo remoto
fdiaz
1
130
Swift Values
fdiaz
0
120
Sisifo o Cómo empezar de nuevo - y otra vez.
fdiaz
0
120
Other Decks in Programming
See All in Programming
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
770
Hypervel - A Coroutine Framework for Laravel Artisans
albertcht
1
130
「テストは愚直&&網羅的に書くほどよい」という誤解 / Test Smarter, Not Harder
munetoshi
0
170
新メンバーも今日から大活躍!SREが支えるスケールし続ける組織のオンボーディング
honmarkhunt
5
7.5k
PicoRuby on Rails
makicamel
2
130
Flutterで備える!Accessibility Nutrition Labels完全ガイド
yuukiw00w
0
160
チームのテスト力を総合的に鍛えて品質、スピード、レジリエンスを共立させる/Testing approach that improves quality, speed, and resilience
goyoki
5
900
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
650
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
690
XP, Testing and ninja testing
m_seki
3
250
なぜ適用するか、移行して理解するClean Architecture 〜構造を超えて設計を継承する〜 / Why Apply, Migrate and Understand Clean Architecture - Inherit Design Beyond Structure
seike460
PRO
3
770
明示と暗黙 ー PHPとGoの インターフェイスの違いを知る
shimabox
2
520
Featured
See All Featured
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Documentation Writing (for coders)
carmenintech
72
4.9k
Building a Modern Day E-commerce SEO Strategy
aleyda
42
7.4k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
20
1.3k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
138
34k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.4k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
18
970
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
Rails Girls Zürich Keynote
gr2m
95
14k
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