Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building a sustainable codebase with FP - Elixi...

Building a sustainable codebase with FP - ElixirConfEU

As software engineers we are always trying to be more productive, to deliver better code, and to have a faster development feedback. In this talk, we’ll explore how functional programming, tests and hexagonal architecture can perform great together in order to support a maintainable codebase for hundreds of engineers and services. Diving deeper on how we can levarage hexagonal architecture with dependency rejection in order to decouple decisions from effects, resulting in a code that is easier to reason, compose and test. The codebase is not the only one that take advantages from that, but also the developers. It helps everyone feels more comfortable and engaged about maintaining good practices. This is already proven to work really well at Nubank, which is considered the best bank in Brazil according to Forbes.

Carolina Pascale Campos

June 19, 2020
Tweet

More Decks by Carolina Pascale Campos

Other Decks in Programming

Transcript

  1. x y

  2. why not imperative? def block!(card, db, producer) do if Logic.Card.can_block?(card)

    do blocked_card = Logic.Card.block(card) Datomic.Card.update!(blocked_card, db) Producer.Card.status_changed!(blocked_card, producer) end end
  3. why not imperative? def block_all!(customer, card, db, producer) do cards

    |> Enum.map(fn card -> block!(card, db, producer) end) cards_block_notify!(customer, producer) end
  4. why not imperative? def block_all!(customer, card, db, producer) do cards

    |> Enum.map (fn card -> block!(card, db, producer) end) cards_block_notify!(customer, producer) end
  5. why not imperative? def block_all!(customer, card, db, producer) do cards

    |> Enum.map (fn (card) -> block!(card, db, producer) end) cards_block_notify!(customer, producer) end
  6. def block!(card) do if Logic.Card.can_block?(card) do blocked_card = Logic.Card.block(card) %{

    datoms: [ Effect.Card.update(blocked_card)], messages: [ Effect.Card.status_changed(blocked_card)]} end end
  7. easier to compose def block_all(customer, cards) do cards |> Enum.map(fn

    card -> block(card) end) |> Effect.Card.card_blocked_notify(customer) end