Saner apps with the Facade Pattern
Tags: elixir, codequality, refactorit, patterns
Published: 2019-11-11 17:00:00

---
title: "Saner apps with the Facade Pattern"
date: "2019-11-11T17:00:00.00Z"
banner: ./tim-meyer-unsplash.jpg
author: gage-peterson
category: patterns
---

One day the trunk of my 2005 Toyota Camry got stuck. It was an old car, but had been reliable in the past, so it was surprising. My wife showed me how the trunk made a grinding sound when it opened and closed. I discovered the trunk had become detached from this long metal bar that acted as the spring. This metal bar made the trunk float up when you opened it and held it open when you were getting things out. Now it was broken. I attempted, but was unable to fix it. Now it had become a guillotine for hands. Not only that, but it was also super heavy to lift—far more than I would have assumed.

Cars are a great example of good abstraction. Their interface is simple, yet they are complex on the inside. The trunk appeared to be the simplest part of the car, yet it was complex when I looked at how it worked. It hid the weight of the trunk from me for years. The trunk would float up, and that's all I knew.

## The power of an Interface

The idea of an "interface" (also called an "API") exists in software as well. This is because, like cars, software tends to be complex on the inside, but _should_ provide a simple interface on the outside.

### Interfaces hide complexity

The best interfaces hide complexity so the user should never need to "look under the hood" to know how to drive. Otherwise, the abstraction would be unhelpful, and you would have to be an expert mechanic to even use the thing. This is not what you want.

A car's steering wheel is this way. You _could_ say: "please rotate the tire-rod mover counter-clockwise 20 degrees," but you don't have to. You can just say: "turn left here!"

### Interfaces Unify

The other cool part of an interface is it's "combining power" - meaning it can help bring many different parts of a machine together into one. For instance, both the steering wheel and the brakes are completely different parts of the car. Even the stereo and the heat are right next to each other in the interface, yet are completely separate subsystems. The interface of the car combines them into a seamless interface.

In a software context, imagine you're making a new API endpoint for your microservice. You might get your data from joining 4 different tables, then doing some in-memory calculation. Not only that, but you mix that with some data from an external API. That would be very complex if another person had to understand all that and do it themselves. But with a nice interface, the user will never be the wiser. You could even refactor it in the future to make it simpler, and nobody's code would be broken (I can dream can't I?).

## The Facade Pattern

There are many ways to create interfaces in different programming languages. One way is to make some of the functions private, so that other ones operate as the public API. In Elixir, you can change a function to be private (unable to be accessed by other files) by just a bit of syntax—`defp <function name>`, instead of `def <function name>` (note the `p`). For example:

```elixir
defmodule MyApp.Example do

 # I'm public
 def public_add(a, b) do
 private_add(a,b)
 end

 # I'm a private, helper function
 defp private_add(a, b) do
 a + b
 end
end
```

\*_(NOTE:_ I'm going to use Elixir for all my examples in this article, because that's the primary backend language we use at Podium, but, this could be used in any language. So long as you understand the example above, you should be able to follow the rest of the article)\*

These constructs only work on a file level. But **what happens if you want to "hide" _a lot of files_ under one interface?** This is where the Facade pattern comes into play.

> The Facade Pattern is a design pattern<sup>[1](#footnotes)</sup> where a module/class provides a simplified interface to a larger body of code.

That's cool, but how do we implement that in Elixir?

## File structure

To start, we organize things the way Phoenix (the web framework for Elixir) recommends — using the "context" pattern. If you're unfamiliar, never fear, it's the pattern I'm going to describe in this article with small additions, primarily the presence of the Facade file. If you're curious you can read about it in the [Phoenix docs](https://hexdocs.pm/phoenix/contexts.html).

All contexts have a name; which, in our example below, there is a `widgets` and an `orgs` context.

These both have a file outside their folder with the same name (`widgets.ex` and `orgs.ex`). These two files are the **facades**. They act as the **Public API** to their sub-modules in the `widgets/` and `orgs/` folders, respectively.

```
lib
├── your_app_web/
└── your_app/
 ├── widgets.ex (<-- facade)
 ├── widgets/ (<-- context folder)
 │ └── private/ (<-- Widgets' private modules)
 │ ├── create.ex (<-- private function file)
 │ └── update.ex (<-- private function file)
 │
 ├── orgs.ex (<-- facade)
 └── orgs/ (<-- context folder)
 └── private/ (<-- Orgs' private modules)
 └── whitelist.ex (<-- private function file)

```

Now let's talk about each of these files, in turn, to understand their purpose more and the rules that govern them.

## The Facade File (Public API)

Facade files adhere to the following rules:

- They **Don't contain any `def`s, only `defdelegates`.** (See the [defdelegate docs](https://hexdocs.pm/elixir/Kernel.html#defdelegate/2), also explained below)
- They are **_the main place of documentation_** for the context's API.
- Named plurally (`Orgs` not `Org`). This allows the name `Org` to be used for a database struct. It's also the convention that Phoenix uses.
- Each `defdelegate` should have docs of _why_ it exists, _what_ it does, and a _working_ example. ([Doctests](https://elixir-lang.org/getting-started/mix-otp/docs-tests-and-with.html#doctests) helps with the _working_ part)

**Example of a context's facade file:**

```elixir
defmodule YourApp.Widgets do
 @moduledoc """
 A widget is a unit of sale...
 """
 alias YourApp.Widgets.Private.{
 Create,
 Update,
 }

 @doc """
 Create a widget in the database. Any configuration options not specified will
 be provided with defaults.

 # Example

 iex> {:ok, id} = Widgets.create()
 """
 defdelegate create(config \\ %{}), to: Create, as: :call

 @doc """
 Update a widget's configuration options. If the update is a no-op it will return an error.

 # Example

 iex> {:ok, id} = Widgets.create()
 iex> Widgets.update(id, color: "red")
 """
 defdelegate update(id, config), to: Update, as: :call
end
```

The `defdelegate` might be unfamiliar to you, so let me explain it. It's a part of the Elixir programming language, although not well known. I think it's best explained with an example.

This:

```elixir
defdelegate update(id, config),
 to: Update,
 as: :call
```

is the same as this:

```elixir
# 🚫 Don't do this, just an example
def update(id, config) do
 Update.call(id, config)
end
```

## Private Function Files

Private function files adhere to the following rules:

- Their **_filename matches the name of the function they represent_**.
- They have a **_single exposed function_** named `call` at the top of the module.
- They must **_never be accessed directly_**, but rather through the facade.
- Should have `@moduledoc false` at the top so they are hidden from the generated documentation.

**Example of a private function file:**

```elixir
defmodule YourApp.Widgets.Private.Create do
 @moduledoc false

 # this is the only public function
 def call(config \\ %{}) do
 # do stuff
 end

 defp helper_function() do
 # ...
 end
end

```

#### What does Private mean?

Public vs Private here means that **different contexts (Widgets and Orgs) should never reference the other's private modules directly**. For example, if `widgets/private/create.ex`, needs access the functionality in `orgs/private/whitelist.ex` it should go through the facade `Orgs.whitelist()` rather than going directly to `Orgs.Private.Whitelist.call()`.

If it looks like this, you're doing it wrong:

```elixir
defmodule YourApp.Widgets.Private.Create do
 # ❌ BAD, this has a `Private` in the alias, and it's not in the same context.
 alias YourApp.Orgs.Private.Whitelist

 def call() do
 # 🚩 Red flag, shouldn't see `.call` in your code
 Whitelist.call()
 end
end
```

Example of doing it right:

```elixir
defmodule YourApp.Widgets.Private.Create do
 # ✅ Good, you only alias the facade
 alias YourApp.Orgs

 def call() do
 # ✅ Good no `.call` in the your code
 Orgs.whitelist()
 end
end
```

If you're wondering about why I have an extra level of nesting using the `private/` folder and the `.Private.` in the module name, the reason is, it will make it more obvious that you're doing things wrong because you'll see `Private` in your `alias ...` line and, hopefully, rethink your decisions. I even dream that someday I'll write my own linting rule to look for people aliasing private modules, but haven't done it yet.

Another benefit to nesting under the `Private` is that auto-complete will work better in `iex` and VSCode, because you'll see the right functions first, rather than the modules (modules are usually listed first for some reason).

Also note that it's fine to have files that aren't listed in the context, but are in the Private folder. I often have a `private/util.ex` file to share functionality between
the different private modules that are all in the same folder.

## 10% pattern 90% design

Although this pattern has helped me a lot in my projects, I will say that the main thing it did for me is _force me to think about my API's_.
Because when you have one file dedicated to the interface of your sub-modules, it's a lot easier to spot functions that do the same thing,
to spot naming inconsistencies, and it becomes a lot more obvious when something doesn't have a `@doc` at the top of the function.

Despite this, _**if you don't care about your API's, it's not going to make any difference.**_

> "If your application is difficult to use from `iex`\* your APIs are probably wrong"
>
> ~ [**Aaron Renner**](https://www.youtube.com/watch?v=Ue--hvFzr0o&index=9&list=PLqj39LCvnOWaxI87jVkxSdtjG8tlhl7U6)

Some recommendations would be:

- The **first** argument is the id of the context (where it makes sense). For instance, do `Widget.update(id, settings)` _not_ `Widget.update(settings, id)`
- Don't stutter in your APIs, meaning, do `Widget.create()` _not_ `Widget.create_widget()`.
- Make the names work well together and are guessable. For instance all functions that **get** something start with `get_`. I find it useful to group functions this way due to autocomplete. I can always start typing `Widget.get_...` and then it will tell me the different ways I can do it. Some style guides hate this, but I personally find it useful.
- Don't pass in arguments that you could get from the database. For instance, don't pass in `Org.get_widgets(id, widget_ids)` just because the front-end happens to have those ids. It's better to do `Org.get_widgets(id)` even if it's a little slower. This is especially important because of security (it's easy to forget to filter out ones that aren't owned by the user).

## FAQs

### 1. Isn't it a bit crazy to have NO `def`s in the Facade? Why can't we move them out into a new file when they get too big?

The main reason I made a rule about only using `defdelegate` as opposed to normal `def`s is the Facade is _public_. When I say public, think "town square" or "neighborhood park". Everybody owns it and everyone needs to take care of it. Its main purpose is to be a sort of crossroads into other modules.

While this may _seem harmless_, over time, it's **very likely people will put all their code into this file** until it becomes thousands of lines long. A "Tragedy of the Commons" occurs:

> The tragedy of the commons is a situation in a shared-resource system where individual users, acting independently according to their self-interest, behave contrary to the common good of all users by depleting or spoiling the shared resource through their collective action.
> ~ [Wikipedia](https://en.wikipedia.org/wiki/Tragedy_of_the_commons)

When everybody is trying to get their ticket done, they are aren't _too_ concerned with making sure the facade file stays clean, _especially if nobody else is_. This leads to everyone adding their 1 line. Nobody is incentivized to pull out the function into a new file, and so nobody does.

This gets even worse the more helper functions (namely `defp`s) you get in this file, because it's unclear which ones are reused and which ones are there to make some other function shorter.

Pulling the implementation into a new function file doesn't quite solve the tragedy of the commons problem, but it limits its effect.

So keep facade files to `@docs`s, `@spec`s and `defdelegates`. You'll be happier if you do. While you're at it, make sure there's a good `@moduledoc`.

Also, it's important to always remember to design for a nice experience using your app via the REPL (`iex`). Why? Because REPLs It allows you to see things really work without the mocking that you would have to do in tests. I also find when you are forced to type everything into a REPL the really long function names, and complex argument lists start to become a lot more apparent.

### 2. Doesn't this mean it takes more jumps to get to the right file?

Yeah, it does if you're following the references directly. However, I can take advantage of the fact that function files are named the same as the function they represent and just use a file finder as I have in VSCode with `⌘-P` (on a Mac, probably `CTRL-P` on Windows?). So if I see `Org.whitelist()`, I know if I do `⌘-P` and start typing `whitelist...`, this will be quite a bit faster than digging through a huge file with all the functions in it, don't you think?

### 3. This seems like too much work. How can we make it easier?

I'm glad you asked (you didn't 😂, but just go with it). Code Generators!

## Code Generators

One barrier to implementing this pattern is the fact that it's more work. Namely in modifying the facade file and creating a new file every time you want to put a function on the context, rather than doing `def` in an existing file.

To fix this problem, I made a `mix` command (`mix gen.fn`) to generate new function files and update existing facade and function files. This command even generates a failing test to hint you towards doing TDD. Not to mention a few `# TODO:...` comments to make [credo](https://github.com/rrrene/credo) force you to write some documentation.

It works like this:

```
λ ~/lib/your_app/ mix gen.fn "Email.feedback_email_contents(user_metadata, orgs, feedback)"

./lib/your_app/email.ex doesn't exist, creating...
File wrote to: ./lib/your_app/email.ex
File wrote to: ./lib/your_app/email/feedback_email_contents.ex
File wrote to: ./test/your_app/email/feedback_email_contents_test.exs
File modified: ./lib/your_app/email.ex
```

[Here's the mix task.](https://gist.github.com/justgage/0ad132409d0a91db88db5bc6f84666b3) It's not a super clean implementation, but might serve you as a thing that you could change to suit your needs.

## Concrete benefits

Some of the most concrete benefits my team and I have experienced are:

1. Functions make more sense in context. It's easier to know that I'm creating a widget when I do `Widgets.create()` rather than `Create.call`.
2. Easier to remember what to alias. I can `alias Widget` instead of the three or four functions I need from it.
3. Because of the previous point, it is super easy to use this API in IEx.
4. Nothing is tied to the API endpoints, so it's easy to write a mix task that does the same thing.
5. People write documentation! Crazy!
6. Because the public functions are reusable, they get reused! I've even implemented new functions out existing ones, which feels good.
7. The facade file looks very clean, which helps people feel like our app is something we take care of. [No broken windows.](https://en.wikipedia.org/wiki/Broken_windows_theory)

## Conclusion

I hope you'll try this pattern out, it has helped me find and reuse code. I no longer feel like I'm digging through the guts of my car to just understand how to drive it.

<h3 id="footnotes">Footnotes</h3>

1. [Software design pattern](https://en.wikipedia.org/wiki/Software_design_pattern), _if you're unfamiliar, are essentially templates of how to layout your code. They usually aren't embodied in a library although maybe in some cases they could be. For my purposes I'm not going to use any libraries, only using a bit of code that generates the file structure that I'm looking for that I'll include at the end._