<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gage</title>
    <description>The latest articles on DEV Community by Gage (@justgage).</description>
    <link>https://dev.to/justgage</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2746%2Fcdfe408a-4ee0-485d-93d5-65dd2f7a47ca.jpg</url>
      <title>DEV Community: Gage</title>
      <link>https://dev.to/justgage</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/justgage"/>
    <language>en</language>
    <item>
      <title>Stop Stressing Users OUT! 😳🙅🏽‍♀️</title>
      <dc:creator>Gage</dc:creator>
      <pubDate>Fri, 07 May 2021 16:23:48 +0000</pubDate>
      <link>https://dev.to/justgage/subtle-ux-tricks-for-calm-36nf</link>
      <guid>https://dev.to/justgage/subtle-ux-tricks-for-calm-36nf</guid>
      <description>&lt;p&gt;Lately I've been working on my project "Hyper Writer" which is &lt;em&gt;supposed to&lt;/em&gt; help me to write more.&lt;/p&gt;

&lt;p&gt;One of the ways it does this is by trying to convince you to write 750 words each day without editing.&lt;/p&gt;

&lt;p&gt;This is great because it acts as a sort of "mind dump" that helps you get your thoughts out and find things that would be great to write about. &lt;/p&gt;

&lt;p&gt;The problem is, I wasn't doing it.&lt;/p&gt;

&lt;p&gt;At first I tried to introduce a sort of "streak calendar" which would color days you've written and leave the other ones a depressing gray color:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5cnYgh-b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xoqclnpnvapmw4d896kv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5cnYgh-b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xoqclnpnvapmw4d896kv.png" alt="Screen Shot 2021-05-07 at 6.03.04 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But lately when I pulled it up I just kind of felt this &lt;em&gt;dread&lt;/em&gt;. I'm a busy parent of 3 small kids... I don't have a ton of time to write. Even 30 mins can be a big time commitment for me and often if life gets in the way I feel like a failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  More positivity, less guilt
&lt;/h2&gt;

&lt;p&gt;The answer of how to improve it came from an unexpected source. Trying to make the landing page.&lt;/p&gt;

&lt;p&gt;The more I read and watched about marketing the more I realized an important principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't talk about the &lt;strong&gt;work&lt;/strong&gt; they are going to have to do&lt;br&gt;
talk about the &lt;strong&gt;benefits&lt;/strong&gt; they are going to get&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I know, sounds like "no duh!" but look at how much work my interface was &lt;em&gt;implying&lt;/em&gt; that I do:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mYtMjDhT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://tmp.f8.n0.cdn.getcloudapp.com/items/8LubeKg7/7e37721e-c817-4588-9c89-73164cfa20fd.jpg%3Fsource%3Dviewer%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bv%3D6ff0b8837aabb17327ae85f673625b4a" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mYtMjDhT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://tmp.f8.n0.cdn.getcloudapp.com/items/8LubeKg7/7e37721e-c817-4588-9c89-73164cfa20fd.jpg%3Fsource%3Dviewer%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bv%3D6ff0b8837aabb17327ae85f673625b4a" alt="Like this"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now compare the new one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ehL9QIrF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://tmp.f8.n0.cdn.getcloudapp.com/items/RBuYRDW8/78486b01-8973-4bac-9a55-0c173984457e.jpg%3Fsource%3Dviewer%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bv%3Dc194366aa760fe0624b1489232943949" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ehL9QIrF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://tmp.f8.n0.cdn.getcloudapp.com/items/RBuYRDW8/78486b01-8973-4bac-9a55-0c173984457e.jpg%3Fsource%3Dviewer%26amp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bamp%3Bv%3Dc194366aa760fe0624b1489232943949" alt="Message about how we should write down today's troubles and unburden your mind"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I click it every day! Let's dive into this a bit more&lt;/p&gt;

&lt;h3&gt;
  
  
  Button Text
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;: 😰 Why would I want to WRITE TODAY'S BONE, that's just more work for me, it's daunting because I know I'm going to have to write 750 words&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;: 🧘‍♀️"&lt;strong&gt;Unburden your mind&lt;/strong&gt;" feels like such a relief! Of course I want to click that button!&lt;/p&gt;

&lt;h3&gt;
  
  
  Worry about Streaks &lt;em&gt;after&lt;/em&gt; you succeed
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;: 😡 the streaks calendar creates an insta-guilt trip at the start of each day. You walk into the app and it says, &lt;em&gt;"guess what! You're already behind again!"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;: 🤗 Hiding the chart till AFTER I succeed stops the instant guilt trip. Also, the message under the button tells you just 1 word is enough, but you &lt;em&gt;know&lt;/em&gt; that when I start writing I'll write more than that. &lt;/p&gt;

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z6lvcP0s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://tmp.f8.n0.cdn.getcloudapp.com/items/12uAj84J/85afae28-c93e-4fe8-bccb-82caf6e600fa.jpg%3Fv%3Df2175897db00aa4bc0874b09710f4195" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z6lvcP0s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://tmp.f8.n0.cdn.getcloudapp.com/items/12uAj84J/85afae28-c93e-4fe8-bccb-82caf6e600fa.jpg%3Fv%3Df2175897db00aa4bc0874b09710f4195" alt="Done it every day"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So maybe try making more changes towards calm and positivity and it see if it helps you too!&lt;/p&gt;

&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;This Microconf talk &lt;a href="https://youtu.be/F_urkVueszI"&gt;Lizards Thru Doorways: Proven Ways to Widen Your Funnel Using Just Your CTAs – Joanna Wiebe&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketingexamples.com/"&gt;Hary's excelent blog on marketing&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ux</category>
      <category>design</category>
    </item>
    <item>
      <title> Don't come in "Guns-A-Blazing'" </title>
      <dc:creator>Gage</dc:creator>
      <pubDate>Fri, 09 Apr 2021 02:11:06 +0000</pubDate>
      <link>https://dev.to/justgage/don-t-come-in-guns-a-blazing-5c19</link>
      <guid>https://dev.to/justgage/don-t-come-in-guns-a-blazing-5c19</guid>
      <description>&lt;p&gt;Have you ever learned something that just &lt;em&gt;blew your mind&lt;/em&gt; and goes against common knowledge or beliefs?&lt;/p&gt;

&lt;p&gt;This recently happened to me when I realized, Single Page Apps (or SPAs for short) are actually way more expensive to build than traditional Server Rendered Multi-page apps (MPAs). When I realized this all I could think was, "I have to tell EVERYBODY! 😱" .&lt;/p&gt;

&lt;p&gt;So what do I do? First step, make sure nobody's saying anything false on &lt;strong&gt;Twitter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I quickly found a guy spreading the doctrine of, "Learn React + APIs" and sharing it with defenseless beginners. So I "set him straight" (typos and all 🙂🤦‍♂️)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SGGgzs7B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ss1bs5xdmaas0ouou39v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SGGgzs7B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ss1bs5xdmaas0ouou39v.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I even tried to soften the blow with the 2nd comment, &lt;em&gt;but&lt;/em&gt; it was still a blow after all.&lt;/p&gt;

&lt;p&gt;His response was quite telling&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_VyF4-11--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hg2w9i2dcpm4edpxs2c2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_VyF4-11--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hg2w9i2dcpm4edpxs2c2.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I had basically just took a guy who was innocently trying to get followers and share some useful information with beginners and had attacked him. What the heck.&lt;/p&gt;

&lt;p&gt;Made me realize my strategy wasn't effective, let alone nice.&lt;/p&gt;

&lt;p&gt;Thing is when I walk into these types of conversations guns raised and ready to attack false ideals I usually just catch innocent bystanders in the crossfire (sorry Vlad).&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's try listening
&lt;/h1&gt;

&lt;p&gt;I recently &lt;a href="https://dev.to/justgage/did-you-choose-the-spa-architecure-4j02"&gt;posted a simple question&lt;/a&gt; on dev.to asking &lt;em&gt;why&lt;/em&gt; people chose to make SPAs instead of traditional Server Rendered apps. You already know I'm super biased on the subject, but at least I was also more curious now.&lt;/p&gt;

&lt;p&gt;I got a response from a nice person about how they built their app using AWS lambda functions, Next.js, Amazon SQS, and more. It sounded ridiculous on the surface, why would they subject themselves so much vendor lock in on top of the complexity of a normal SPA when normal Postgres, Redis, and some nice MVC framework would have got the job done?&lt;/p&gt;

&lt;p&gt;Luckily instead I decided to just &lt;em&gt;listen&lt;/em&gt; and ask questions to understand &lt;em&gt;why they thought the way they did.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We had a long back and forth conversation and you know what happened? Their arguments made perfect sense!&lt;/p&gt;

&lt;p&gt;They were able to not have to worry about &lt;em&gt;any&lt;/em&gt; server upgrades and didn't have to shard their database anymore! Not only that they didn't have to worry about &lt;em&gt;where&lt;/em&gt; their server was running, but it would also just run at the nearest data center. What about local development? Well, there's some local DB mocking for that. Sure there was some vendor lock-in but they traded off a lot of the effort normally being put into keeping a traditional app up and running. Huh 🤔.&lt;/p&gt;

&lt;p&gt;After all this questioning I was tempted to open my mouth again, still sounded harder than how I would build it, but then realized... I had &lt;strong&gt;&lt;em&gt;never&lt;/em&gt;&lt;/strong&gt; made an app this way before! I had NO experience, zero, zilch, nada.&lt;/p&gt;

&lt;p&gt;I felt like before I had so much experience, having seen both sides (SPA and MPA), well it turns out there was another side 🤯, even a whole spectrum of choices that I've never even tried.&lt;/p&gt;

&lt;p&gt;Maybe I'm right, maybe he is, doesn't really matter. I learned a lot from putting down my "guns of justice" down and talking around a campfire, and I think you could too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7X1gYryF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97ifs46z4h8olqnbrjer.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7X1gYryF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97ifs46z4h8olqnbrjer.jpg" alt="andreas-wagner-eI-nOb1K5gE-unsplash"&gt;&lt;/a&gt; &lt;br&gt;
(Photo by &lt;a href="https://unsplash.com/@waguluz_?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Andreas Wagner&lt;/a&gt; on &lt;a href="https://unsplash.com/@waguluz_?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;DON'T FORGET TO LIKE COMMENT AND SUBSCRIBE, RING THAT BELL ICON SO YOU CAN KNOW WHEN ALL MY NEW BLOG POSTS COME OUT.&lt;/p&gt;

&lt;p&gt;J/K, but you can leave a comment if you want.&lt;/p&gt;

&lt;p&gt;Peace ✌️.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;P.S: My coworker shared this with me and I think it relates&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NSnqkHj0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kgf23nsl6m9oentkkfzh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NSnqkHj0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kgf23nsl6m9oentkkfzh.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>writing</category>
      <category>empathy</category>
      <category>softskills</category>
    </item>
    <item>
      <title>Why did you choose the SPA architecure?</title>
      <dc:creator>Gage</dc:creator>
      <pubDate>Tue, 06 Apr 2021 23:12:23 +0000</pubDate>
      <link>https://dev.to/justgage/did-you-choose-the-spa-architecure-4j02</link>
      <guid>https://dev.to/justgage/did-you-choose-the-spa-architecure-4j02</guid>
      <description>&lt;p&gt;Single Page Apps (SPA) + APIs seem to be the default nowadays over more traditional Multi-page apps Ruby on Rails / PHP type server-rendered HTML.&lt;/p&gt;

&lt;p&gt;I want to write an article about why I think MPAs are still a valid a nice way to make applications but I'm not sure where people are at right now besides they seem to be picking SPAs almost exclusively. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Was React + APIs the only thing you learned?&lt;/li&gt;
&lt;li&gt;Why did you pick SPAs personally?&lt;/li&gt;
&lt;li&gt;Why did your company pick a SPA if they did?&lt;/li&gt;
&lt;li&gt;Why do you think SPAs became the default for most orgs? Or do you think they aren't?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have no idea what the difference between a SPA or MPA is then I am curious about that as well (I just want to hear from you guys I guess 🤗). &lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@soymeraki?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Javier Allegue Barros&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/choice?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Published is better than perfect</title>
      <dc:creator>Gage</dc:creator>
      <pubDate>Tue, 06 Apr 2021 15:58:54 +0000</pubDate>
      <link>https://dev.to/justgage/published-is-better-than-perfect-34g9</link>
      <guid>https://dev.to/justgage/published-is-better-than-perfect-34g9</guid>
      <description>&lt;p&gt;I'm kind of a perfectionist. I love to read a blog post that's been crafted and polished over weeks and weeks of work like &lt;a href="http://paulgraham.com/articles.html"&gt;Paul Graham's essays&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But I also have a super bad habit of not actually publishing anything. I have tons of drafts, thousands of notes, all of them are &lt;em&gt;just not good enough&lt;/em&gt;. I'm afraid that people will make fun of my ideas or poke holes in them that if only I poured in a few more hours into them I could have made it all airtight.&lt;/p&gt;

&lt;p&gt;However, when I was &lt;a href="https://youtu.be/3i1lNJPY-4Q"&gt;watching a video&lt;/a&gt; about how a man learned Italian way faster than most people can. Most people get hung up in following ridged grammar rules but often end up years in not really being fluent.&lt;/p&gt;

&lt;p&gt;What he decided to do instead was just learn the most common words of the language (the most useful ones) and just start stringing them together in the ways that most make sense to him. Sure he looks like a total "noob" to any native speaker but that's not the point. He didn't get hung up on hiding his talking till he was, "ready".&lt;/p&gt;

&lt;p&gt;He made a good argument for this:&lt;/p&gt;

&lt;p&gt;language is not like math. Math has right and wrong answers.&lt;/p&gt;

&lt;p&gt;If my son says, "&lt;em&gt;I ated a Apple&lt;/em&gt;" I'm &lt;strong&gt;not&lt;/strong&gt; going to correct him. He said words and I understood them. That's all part of the expressive human experience.&lt;/p&gt;

&lt;p&gt;Basically, so long as you can relay your message &lt;em&gt;clear enough&lt;/em&gt; you're communicating!&lt;/p&gt;

&lt;p&gt;I think the same applies to writing. You may not be good at it (I know I'm not) but if you're not sharing you're not learning.&lt;/p&gt;

&lt;p&gt;Some people even use &lt;a href="https://dev.to/swyx/blogpost-annealing-pod"&gt;publishing as a perfecting process&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;...&lt;em&gt;with an annealing policy will usually improve in quality after publication. More exposure = More "heat" = More quality.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I really like this idea. Nothing is going to ever be perfect unless you &lt;strong&gt;put it into the real world&lt;/strong&gt;. There's no shame in modifying your post after you post it! Once it's out there you'll be so much more motivated to fix the problems with it 🙃. This post had 10 grammar errors that I fixed a day after writing it.&lt;/p&gt;

&lt;p&gt;So just freakin' write it and push &lt;strong&gt;publish&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Published is better than perfect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PS*: If it makes you feel any better just take any popular blogger and stick it into Grammarly, you'll see their post isn't perfect either* 😅&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@bank_phrom?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Bank Phrom&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/newspaper?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>writing</category>
    </item>
    <item>
      <title>Saner apps with the Facade Pattern</title>
      <dc:creator>Gage</dc:creator>
      <pubDate>Mon, 11 Nov 2019 17:00:00 +0000</pubDate>
      <link>https://dev.to/justgage/saner-apps-with-the-facade-pattern-4e29</link>
      <guid>https://dev.to/justgage/saner-apps-with-the-facade-pattern-4e29</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The power of an Interface
&lt;/h2&gt;

&lt;p&gt;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 &lt;em&gt;should&lt;/em&gt; provide a simple interface on the outside.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interfaces hide complexity
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Interfaces Unify
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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?).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Facade Pattern
&lt;/h2&gt;

&lt;p&gt;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—&lt;code&gt;defp &amp;lt;function name&amp;gt;&lt;/code&gt;, instead of &lt;code&gt;def &amp;lt;function name&amp;gt;&lt;/code&gt; (note the &lt;code&gt;p&lt;/code&gt;). For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Example&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;

 &lt;span class="c1"&gt;# I'm public&lt;/span&gt;
 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;public_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="n"&gt;private_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;

 &lt;span class="c1"&gt;# I'm a private, helper function&lt;/span&gt;
 &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;private_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;(NOTE:&lt;/em&gt; 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)*&lt;/p&gt;

&lt;p&gt;These constructs only work on a file level. But &lt;strong&gt;what happens if you want to "hide" &lt;em&gt;a lot of files&lt;/em&gt; under one interface?&lt;/strong&gt; This is where the Facade pattern comes into play.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Facade Pattern is a design pattern&lt;sup&gt;1&lt;/sup&gt; where a module/class provides a simplified interface to a larger body of code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's cool, but how do we implement that in Elixir?&lt;/p&gt;

&lt;h2&gt;
  
  
  File structure
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://hexdocs.pm/phoenix/contexts.html"&gt;Phoenix docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All contexts have a name; which, in our example below, there is a &lt;code&gt;widgets&lt;/code&gt; and an &lt;code&gt;orgs&lt;/code&gt; context.&lt;/p&gt;

&lt;p&gt;These both have a file outside their folder with the same name (&lt;code&gt;widgets.ex&lt;/code&gt; and &lt;code&gt;orgs.ex&lt;/code&gt;). These two files are the &lt;strong&gt;facades&lt;/strong&gt;. They act as the &lt;strong&gt;Public API&lt;/strong&gt; to their sub-modules in the &lt;code&gt;widgets/&lt;/code&gt; and &lt;code&gt;orgs/&lt;/code&gt; folders, respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lib
├── your_app_web/
└── your_app/
 ├── widgets.ex (&amp;lt;-- facade)
 ├── widgets/ (&amp;lt;-- context folder)
 │ └── private/ (&amp;lt;-- Widgets' private modules)
 │ ├── create.ex (&amp;lt;-- private function file)
 │ └── update.ex (&amp;lt;-- private function file)
 │
 ├── orgs.ex (&amp;lt;-- facade)
 └── orgs/ (&amp;lt;-- context folder)
 └── private/ (&amp;lt;-- Orgs' private modules)
 └── whitelist.ex (&amp;lt;-- private function file)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  The Facade File (Public API)
&lt;/h2&gt;

&lt;p&gt;Facade files adhere to the following rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They &lt;strong&gt;Don't contain any &lt;code&gt;def&lt;/code&gt;s, only &lt;code&gt;defdelegates&lt;/code&gt;.&lt;/strong&gt; (See the &lt;a href="https://hexdocs.pm/elixir/Kernel.html#defdelegate/2"&gt;defdelegate docs&lt;/a&gt;, also explained below)&lt;/li&gt;
&lt;li&gt;They are &lt;strong&gt;&lt;em&gt;the main place of documentation&lt;/em&gt;&lt;/strong&gt; for the context's API.&lt;/li&gt;
&lt;li&gt;Named plurally (&lt;code&gt;Orgs&lt;/code&gt; not &lt;code&gt;Org&lt;/code&gt;). This allows the name &lt;code&gt;Org&lt;/code&gt; to be used for a database struct. It's also the convention that Phoenix uses.&lt;/li&gt;
&lt;li&gt;Each &lt;code&gt;defdelegate&lt;/code&gt; should have docs of &lt;em&gt;why&lt;/em&gt; it exists, &lt;em&gt;what&lt;/em&gt; it does, and a &lt;em&gt;working&lt;/em&gt; example. (&lt;a href="https://elixir-lang.org/getting-started/mix-otp/docs-tests-and-with.html#doctests"&gt;Doctests&lt;/a&gt; helps with the &lt;em&gt;working&lt;/em&gt; part)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example of a context's facade file:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;YourApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Widgets&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="sd"&gt;"""
 A widget is a unit of sale...
 """&lt;/span&gt;
 &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;YourApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Widgets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Private&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="no"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="no"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""
 Create a widget in the database. Any configuration options not specified will
 be provided with defaults.

 # Example

 iex&amp;gt; {:ok, id} = Widgets.create()
 """&lt;/span&gt;
 &lt;span class="k"&gt;defdelegate&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="p"&gt;\\&lt;/span&gt; &lt;span class="p"&gt;%{}),&lt;/span&gt; &lt;span class="ss"&gt;to:&lt;/span&gt; &lt;span class="no"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as:&lt;/span&gt; &lt;span class="ss"&gt;:call&lt;/span&gt;

 &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""
 Update a widget's configuration options. If the update is a no-op it will return an error.

 # Example

 iex&amp;gt; {:ok, id} = Widgets.create()
 iex&amp;gt; Widgets.update(id, color: "red")
 """&lt;/span&gt;
 &lt;span class="k"&gt;defdelegate&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;to:&lt;/span&gt; &lt;span class="no"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as:&lt;/span&gt; &lt;span class="ss"&gt;:call&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;defdelegate&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;This:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defdelegate&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
 &lt;span class="ss"&gt;to:&lt;/span&gt; &lt;span class="no"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="ss"&gt;as:&lt;/span&gt; &lt;span class="ss"&gt;:call&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is the same as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 🚫 Don't do this, just an example&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="no"&gt;Update&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Private Function Files
&lt;/h2&gt;

&lt;p&gt;Private function files adhere to the following rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Their &lt;strong&gt;&lt;em&gt;filename matches the name of the function they represent&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;They have a &lt;strong&gt;&lt;em&gt;single exposed function&lt;/em&gt;&lt;/strong&gt; named &lt;code&gt;call&lt;/code&gt; at the top of the module.&lt;/li&gt;
&lt;li&gt;They must &lt;strong&gt;&lt;em&gt;never be accessed directly&lt;/em&gt;&lt;/strong&gt;, but rather through the facade.&lt;/li&gt;
&lt;li&gt;Should have &lt;code&gt;@moduledoc false&lt;/code&gt; at the top so they are hidden from the generated documentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example of a private function file:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;YourApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Widgets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Private&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Create&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;

 &lt;span class="c1"&gt;# this is the only public function&lt;/span&gt;
 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="p"&gt;\\&lt;/span&gt; &lt;span class="p"&gt;%{})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="c1"&gt;# do stuff&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;

 &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;helper_function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="c1"&gt;# ...&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  What does Private mean?
&lt;/h4&gt;

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

&lt;p&gt;If it looks like this, you're doing it wrong:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;YourApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Widgets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Private&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Create&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="c1"&gt;# ❌ BAD, this has a `Private` in the alias, and it's not in the same context.&lt;/span&gt;
 &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;YourApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Orgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Private&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Whitelist&lt;/span&gt;

 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="c1"&gt;# 🚩 Red flag, shouldn't see `.call` in your code&lt;/span&gt;
 &lt;span class="no"&gt;Whitelist&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example of doing it right:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;YourApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Widgets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Private&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Create&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="c1"&gt;# ✅ Good, you only alias the facade&lt;/span&gt;
 &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;YourApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Orgs&lt;/span&gt;

 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="c1"&gt;# ✅ Good no `.call` in the your code&lt;/span&gt;
 &lt;span class="no"&gt;Orgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're wondering about why I have an extra level of nesting using the &lt;code&gt;private/&lt;/code&gt; folder and the &lt;code&gt;.Private.&lt;/code&gt; in the module name, the reason is, it will make it more obvious that you're doing things wrong because you'll see &lt;code&gt;Private&lt;/code&gt; in your &lt;code&gt;alias ...&lt;/code&gt; 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.&lt;/p&gt;

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

&lt;p&gt;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 &lt;code&gt;private/util.ex&lt;/code&gt; file to share functionality between&lt;br&gt;
the different private modules that are all in the same folder.&lt;/p&gt;
&lt;h2&gt;
  
  
  10% pattern 90% design
&lt;/h2&gt;

&lt;p&gt;Although this pattern has helped me a lot in my projects, I will say that the main thing it did for me is &lt;em&gt;force me to think about my API's&lt;/em&gt;.&lt;br&gt;
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,&lt;br&gt;
to spot naming inconsistencies, and it becomes a lot more obvious when something doesn't have a &lt;code&gt;@doc&lt;/code&gt; at the top of the function.&lt;/p&gt;

&lt;p&gt;Despite this, &lt;em&gt;&lt;strong&gt;if you don't care about your API's, it's not going to make any difference.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If your application is difficult to use from &lt;code&gt;iex&lt;/code&gt;* your APIs are probably wrong"&lt;/p&gt;

&lt;p&gt;~ &lt;a href="https://www.youtube.com/watch?v=Ue--hvFzr0o&amp;amp;index=9&amp;amp;list=PLqj39LCvnOWaxI87jVkxSdtjG8tlhl7U6"&gt;&lt;strong&gt;Aaron Renner&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some recommendations would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;first&lt;/strong&gt; argument is the id of the context (where it makes sense). For instance, do &lt;code&gt;Widget.update(id, settings)&lt;/code&gt; &lt;em&gt;not&lt;/em&gt; &lt;code&gt;Widget.update(settings, id)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Don't stutter in your APIs, meaning, do &lt;code&gt;Widget.create()&lt;/code&gt; &lt;em&gt;not&lt;/em&gt; &lt;code&gt;Widget.create_widget()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Make the names work well together and are guessable. For instance all functions that &lt;strong&gt;get&lt;/strong&gt; something start with &lt;code&gt;get_&lt;/code&gt;. I find it useful to group functions this way due to autocomplete. I can always start typing &lt;code&gt;Widget.get_...&lt;/code&gt; and then it will tell me the different ways I can do it. Some style guides hate this, but I personally find it useful.&lt;/li&gt;
&lt;li&gt;Don't pass in arguments that you could get from the database. For instance, don't pass in &lt;code&gt;Org.get_widgets(id, widget_ids)&lt;/code&gt; just because the front-end happens to have those ids. It's better to do &lt;code&gt;Org.get_widgets(id)&lt;/code&gt; 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).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Isn't it a bit crazy to have NO &lt;code&gt;def&lt;/code&gt;s in the Facade? Why can't we move them out into a new file when they get too big?
&lt;/h3&gt;

&lt;p&gt;The main reason I made a rule about only using &lt;code&gt;defdelegate&lt;/code&gt; as opposed to normal &lt;code&gt;def&lt;/code&gt;s is the Facade is &lt;em&gt;public&lt;/em&gt;. 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.&lt;/p&gt;

&lt;p&gt;While this may &lt;em&gt;seem harmless&lt;/em&gt;, over time, it's &lt;strong&gt;very likely people will put all their code into this file&lt;/strong&gt; until it becomes thousands of lines long. A "Tragedy of the Commons" occurs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;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.&lt;br&gt;
~ &lt;a href="https://en.wikipedia.org/wiki/Tragedy_of_the_commons"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When everybody is trying to get their ticket done, they are aren't &lt;em&gt;too&lt;/em&gt; concerned with making sure the facade file stays clean, &lt;em&gt;especially if nobody else is&lt;/em&gt;. This leads to everyone adding their 1 line. Nobody is incentivized to pull out the function into a new file, and so nobody does.&lt;/p&gt;

&lt;p&gt;This gets even worse the more helper functions (namely &lt;code&gt;defp&lt;/code&gt;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.&lt;/p&gt;

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

&lt;p&gt;So keep facade files to &lt;code&gt;@docs&lt;/code&gt;s, &lt;code&gt;@spec&lt;/code&gt;s and &lt;code&gt;defdelegates&lt;/code&gt;. You'll be happier if you do. While you're at it, make sure there's a good &lt;code&gt;@moduledoc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also, it's important to always remember to design for a nice experience using your app via the REPL (&lt;code&gt;iex&lt;/code&gt;). 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.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Doesn't this mean it takes more jumps to get to the right file?
&lt;/h3&gt;

&lt;p&gt;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 &lt;code&gt;⌘-P&lt;/code&gt; (on a Mac, probably &lt;code&gt;CTRL-P&lt;/code&gt; on Windows?). So if I see &lt;code&gt;Org.whitelist()&lt;/code&gt;, I know if I do &lt;code&gt;⌘-P&lt;/code&gt; and start typing &lt;code&gt;whitelist...&lt;/code&gt;, this will be quite a bit faster than digging through a huge file with all the functions in it, don't you think?&lt;/p&gt;
&lt;h3&gt;
  
  
  3. This seems like too much work. How can we make it easier?
&lt;/h3&gt;

&lt;p&gt;I'm glad you asked (you didn't 😂, but just go with it). Code Generators!&lt;/p&gt;
&lt;h2&gt;
  
  
  Code Generators
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;def&lt;/code&gt; in an existing file.&lt;/p&gt;

&lt;p&gt;To fix this problem, I made a &lt;code&gt;mix&lt;/code&gt; command (&lt;code&gt;mix gen.fn&lt;/code&gt;) 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 &lt;code&gt;# TODO:...&lt;/code&gt; comments to make &lt;a href="https://github.com/rrrene/credo"&gt;credo&lt;/a&gt; force you to write some documentation.&lt;/p&gt;

&lt;p&gt;It works like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ ~/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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://gist.github.com/justgage/0ad132409d0a91db88db5bc6f84666b3"&gt;Here's the mix task.&lt;/a&gt; It's not a super clean implementation, but might serve you as a thing that you could change to suit your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concrete benefits
&lt;/h2&gt;

&lt;p&gt;Some of the most concrete benefits my team and I have experienced are:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3 id="footnotes"&gt;Footnotes&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Software_design_pattern"&gt;Software design pattern&lt;/a&gt;, &lt;em&gt;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.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>elixir</category>
      <category>codequality</category>
      <category>refactorit</category>
      <category>patterns</category>
    </item>
    <item>
      <title>Hi, I'm Gage</title>
      <dc:creator>Gage</dc:creator>
      <pubDate>Thu, 23 Mar 2017 14:17:16 +0000</pubDate>
      <link>https://dev.to/justgage/hi-im-gage</link>
      <guid>https://dev.to/justgage/hi-im-gage</guid>
      <description>&lt;p&gt;I have been coding since high school.&lt;/p&gt;

&lt;p&gt;You can find me on GitHub as &lt;a href="https://github.com/justgage" rel="noopener noreferrer"&gt;justgage&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I work for Podium&lt;/p&gt;

&lt;p&gt;I mostly program in these languages: Elixir, Ruby, JavaScript, and Elm.&lt;/p&gt;

&lt;p&gt;I am currently learning more about Elm.&lt;/p&gt;

&lt;p&gt;Nice to meet you!&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
