axelson

axelson

Scenic Core Team

8) ElixirConf US 2018 – Growing Applications and Taming Complexity – Aaron Renner

ElixirConf US 2018 – Growing Applications and Taming Complexity – Aaron Renner (@aaronrenner)

Growing an application is hard. We started our app with the best of intentions and promised ourselves we were going to “design it right". However as the app grew, complexity increased, dependencies piled up, and changes that were once small now felt like slogging through mud.

Driven by the need to keep our sanity, we decided to apply ideas from Phoenix’s contexts and Domain Driven Design with the hope that we could put boundaries around the complex parts of our system and keep the code from turning into a tangled rat’s nest. This talk covers many of the lessons we learned along the way, including:

  • How to start tackling complexity by teasing apart the app into multiple layers.
  • How to simplify testing and reduce mental burden by defining contracts between these layers.
  • How to verify contracts using tools like dialyzer, automated tests and mocks.
  • How to document these contracts and use them to guide the application design.

After applying these ideas to our codebase for almost a year, we’re eager to share our experiences and provide strategies you can use to tame complexity in your own applications.

Audience: Intermediate
Topics: phoenix

All talks are available in the ElixirConf US 2018 Talks List or via the elixirconf2018 tag

First Post!

bartlomiej

bartlomiej

I am having mixed feelings about this, the examples in repository (GitHub - aaronrenner/crowdfundr: Example crowdfunding app for ElixirConf · GitHub) even define some very common cases like user entering an email that is already used as an exception (Crowdfundr.EmailAlreadyRegisteredError) and then use that in {:error, exception} tuple.

I am just learning Elixir but I have went through some materials already and I must say this approach looks totally foreign to me. I would even say that it looks like a total oposite of why I turned to Elixir in the first place. The Behaviour/Impl/DefaultImpl thing reminds me too much of the “interface with single implementation” ceremony that used to be common in some OO languages.

What do you think? I would love to hear what others have to say.

Most Liked

slashdotdash

slashdotdash

The behaviour/impl module and separate implementation approach is used by the new Elixir Telemetry library.

aaronrenner

aaronrenner

Phoenix Core Team

I know it’s over a year later, but I just posted an in-depth article covering the layering and swapping mechanisms I gave an overview of in this talk.

LostKobrakai

LostKobrakai

I‘ve not had a look at the repo yet, but it‘s probably created by driving the point of the talk all the way to make a point.

On the other hand having clear interfaces is something, which is by no means inherently OO. Interfaces are something your code has even if they‘re not written out somewhere explicitly. At the least you should have it as soon as there are multiple implementations, which can be switched out (and as @josevalim argued when creating Mox, this stands also if a second implementation is just used for testing). This was one point in the talk, that it makes testing easier. But I‘m with you that it‘s quite a bit of ceremony if there‘s only one implementation. It just makes is super clear, which functions are meant to be public interface vs. what is implementation detail. In bigger projects, this might otherwise not be as clear.

Naming errors is imo a good thing like anywhere else in programming, especially for the common cases, which are the ones one has to deal with all the time. It could‘ve been an atom instead of an exception struct, but the latter has the ability to later be enhanced with metadata, while with a plain atom to start with the interface would probably need to change in a backwards incompatible way.

Last Post!

slashdotdash

slashdotdash

The behaviour/impl module and separate implementation approach is used by the new Elixir Telemetry library .

Unfortunately this no longer applies as the Telemetry library has been rewritten from Elixir to Erlang.

Where Next?

Popular in Talks Top

axelson
ElixirConf 2017 - Cajoling the Bird: How we squeezed more out of Phoenix PubSub- Simon Zelazny Grindr is a m...
New
axelson
Posting a little bit late today but here you go: ElixirConf 2017 - Elixir + Neo4j - Regina Imhoff Neo4j is ...
New
axelson
ElixirConf 2017 - Closing Keynote - @chrismccord All talks are available in the Elixir Conf 2017 Talks List o...
New
New
Lawrence_elixir
@voltone - Security advocate, BEAM enthusiast Learn you some ‘ssl’ for much security! Talk in three words: TLS, security, troubleshooti...
New
rodrigues
Whether you’re developing a small web site or a large-scale distributed system, Erlang and Elixir are great tools for building server-sid...
New
JuanjoA
Hi, I don’t know if I have the post in the right place. I put here in case you might be interested, I am not the author, I just found it...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 130579 1222
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New

We're in Beta

About us Mission Statement