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
Building a sustainable architecture
Search
Marcelo Piva
October 26, 2019
Programming
120
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Building a sustainable architecture
Marcelo Piva
October 26, 2019
More Decks by Marcelo Piva
See All by Marcelo Piva
Maintaining consistency in distributed systems with an effect machine
mpivaa
1
300
Fun with Monads
mpivaa
2
210
Go Pure with ClojureScript
mpivaa
2
190
Other Decks in Programming
See All in Programming
バグを直したら useEffect が消えた
colorful12
3
690
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
590
仕様書を書く前にハーネスを作る - Agent Native開発は「探索を速く、判定を固く」
gotalab555
4
1.7k
まだ間に合う!今年の夏こそSchemeのマクロ展開器を完全理解!
omasanori
0
390
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
510
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
7.6k
運用ダッシュボードの設計を誰も教えてくれないのだけどみなさんどうしてるんですか? - チームに監視するという文化を根付かせるための第一歩を踏みたい -
satoshi256kbyte
1
140
引き算の組織 ― アウトカムとAIに全振りするために辞めたこと ― / Organization by Subtraction
hirokiyamamoto14
PRO
0
280
My Marp Sample
sinoue0108
0
110
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
400
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
1
510
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
170
Featured
See All Featured
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
630
Abbi's Birthday
coloredviolet
3
9.4k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Building the Perfect Custom Keyboard
takai
2
850
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
エンジニアに許された特別な時間の終わり
watany
108
250k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Automating Front-end Workflow
addyosmani
1369
210k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
66
57k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Faster Mobile Websites
deanohume
310
32k
Transcript
Building a sustainable architecture
Marcelo Piva Software Engineer @ Nubank @mpivaa github.com/mpivaa instagram.com/mah.piva
Carolina Pascale Campos Software Engineer @ Nubank @CarolinaPascale github.com/carolpc instagram.com/carolpc
books, coffee, running
motivation
None
smooth learning curve shipped code to production
almost no guidance
why?
None
300+ engineers 300+ services 15M customers
None
patterns among services
functional programming tests △ hexagonal architecture ⬡
functional programming
fp is about pure functions
fp is about referential transparency
��
Consistency Predictability Safety
we need to talk about side effects
not infecting your fp code with imperative code
limit the amount of imperative code
immutability vs mutability
pure functions + immutability
✅ easier to reason ✅ easier to debug
persistent data structures (copy-on-write)
Structural Sharing A =
Structural Sharing A = B =
Structural Sharing
Structural Sharing A
Structural Sharing B
focus on what matters
Class Object Instance Inheritance Polymorphism Abstract Factory Builder Factory Method
Object Pool Prototype Singleton Adapter Bridge Composite Decorator Facade Flyweight Private Class Data Proxy Chain of responsibility Command Interpreter Iterator Mediator Memento Null Object Observer State
None
eliminate shared state so order does not matter
don't have to set up anything up
be as functional as you can
tests △
confidence safety
feedback
accuracy
speed
reliability
✅ accuracy ✅ speed ✅ reliability
why highly testable code?
bonus: generative and property based testing
how to design our code?
high maintainability low tech debt
maintainability is a long term concept
first attempt: hexagonal architecture
inner layer: domain model
second layer: application
third layer: IO
separates business logic from IO
tests in isolation with mocks and stubs
dependency injection
first discover
hard things in OOP can be easy in FP (tests)
boundaries
third layer: IO
hexagonal architecture in FP is natural
push impure code to the boundaries
great discovery!
but, are we leveraring FP to its max?
services need to communicate
None
second layer with imperative code and side effects
why not imperative? harder to reason about harder to compose
harder to test slower feedback
why not imperative? harder to reason about harder to compose
harder to test slower feedback
why not imperative? (block! card datomic producer) ; =>
why not imperative? (defn block! [card datomic producer] (when (logic.card/can-block?
card) (let [locked-card (logic.card/block card)] (datomic.card/update! blocked-card datomic) (producer.card/status-changed! blocked-card producer))))
why not imperative? harder to reason about harder to compose
harder to test slower feedback
why not imperative? (defn block-all! [customer cards datomic producer] (doseq
[card cards] (block! card datomic producer)) (cards-blocked-notify! customer producer))
why not imperative? (defn block-all! [customer cards datomic producer] (doseq
[card cards] (block! card datomic producer)) (cards-blocked-notify! customer producer))
why not imperative? (defn block-all! [customer cards datomic producer] (doseq
[card cards] (block! card datomic producer)) (cards-blocked-notify! customer producer))
why not imperative? harder to reason about harder to compose
harder to test slower feedback
why not imperative? mocks & integration tests
None
Unit Integration E2E
why not imperative? harder to reason about harder to compose
harder to test slower feedback
None
❌ pure functions ❌ tests ❌ maintainability
let's try another approach
declaring effects on the return of functions
decouple decisions from effects
decouple intent from execution
(block card) ; => [{:effects/datoms [...] ; :effects/messages [...]}]
data as first class citizens
declarative
atomic operations
Global dependencies
Global dependencies Dependency injection
Dependency rejection Global dependencies Dependency injection
(defn block [card] (if (logic.card/can-block? card) (let [blocked-card (logic.card/block card)]
(-> e/empty-effects (effect.card/update blocked-card) (effect.card/status-changed blocked-card)))) e/empty-effects))
None
second layer without side effects
become more expressive
✅ pure functions ✅ tests ✅ maintainability
Thanks! We're hiring! https://grnh.se/5fc5f7e51 @mpivaa github.com/mpivaa instagram.com/mah.piva