<?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>Forem: Marcos Brizeno</title>
    <description>The latest articles on Forem by Marcos Brizeno (@marcosx).</description>
    <link>https://forem.com/marcosx</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%2F12483%2Faf5ff8f7-f620-457a-ae98-9d477fa15570.jpg</url>
      <title>Forem: Marcos Brizeno</title>
      <link>https://forem.com/marcosx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/marcosx"/>
    <language>en</language>
    <item>
      <title>Lessons learned from one year with Kubernetes and Istio</title>
      <dc:creator>Marcos Brizeno</dc:creator>
      <pubDate>Wed, 25 Dec 2019 15:41:25 +0000</pubDate>
      <link>https://forem.com/marcosx/lessons-learned-from-one-year-with-kubernetes-and-istio-2p79</link>
      <guid>https://forem.com/marcosx/lessons-learned-from-one-year-with-kubernetes-and-istio-2p79</guid>
      <description>&lt;h1&gt;
  
  
  tl;dr;
&lt;/h1&gt;

&lt;p&gt;We've been happy with all the features of &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; and &lt;a href="https://istio.io/"&gt;Istio&lt;/a&gt; to create a service mesh for APIs and web apps. It comes with a cost and require a team of people willing to sometimes dive deep into the unknown.&lt;/p&gt;

&lt;p&gt;Kubernetes is pretty mature and if you are using a cloud provider you can get up and running pretty fast. Keeping it up to date is also fairly straightforward and, most of the time, upgrading components won't even require downtime.&lt;/p&gt;

&lt;p&gt;Istio on the other hand requires a lot more time to get right and, although it adds a really &lt;a href="https://istio.io/docs/concepts/what-is-istio/#core-features"&gt;wide array of capabilities&lt;/a&gt;, it has a considerable maintenance cost.&lt;/p&gt;

&lt;p&gt;If you don't have a safe environment to learn and fail (be it due to time constraints or the criticality of projects) I recommend sticking with just Kubernetes, you'll get a lot from using it. Meanwhile try to look at service mesh capabilities since you'll probably find the need for them early on, maybe try implementing them one at a time.&lt;/p&gt;

&lt;p&gt;If you want more details on why, keep reading :)&lt;/p&gt;

&lt;h1&gt;
  
  
  Before you begin
&lt;/h1&gt;

&lt;p&gt;Let's just get the fact that Kubernetes is complex out of the way early on this article. There are many components for you to learn and figure out the right configuration in multiple yaml files until you get your application up and running.&lt;/p&gt;

&lt;p&gt;Imagine if you were part of a team or company that has to run 100+ microservices. Even if all of them are extremely well designed and developed into a standard tech stack, following all the best practices and building quality into every step of the way, it is still a pretty hard and complex problem to solve.&lt;/p&gt;

&lt;p&gt;Running a distributed service oriented architecture is really complex, there's no easy way to do it (and if anyone tells you there is they either have never done it or are straight up lying). In my opinion Kubernetes offers a programatic and pretty standardize way to deal with all requirements to run a distributed architecture. The API is well designed and after the initial learning curve you'll find to be quite powerful.&lt;/p&gt;

&lt;p&gt;Kubernetes will require you to really understand your applications. How can you signal that a service is ready to receive traffic? How can you signal they are unhealthy and need to be restarted? How many instances be created? How to route traffic between different versions of services?&lt;/p&gt;

&lt;p&gt;In my experience as a developer these questions were rarely asked, but to really benefit from Kubernetes and Istio you need to have answers sooner rather than later.&lt;/p&gt;

&lt;p&gt;I want to highlight two main areas which I think are really important in a distributed environment: compute engine (where applications are running) and service mesh (how all the services integrate with each other).&lt;/p&gt;

&lt;h1&gt;
  
  
  Compute engine
&lt;/h1&gt;

&lt;p&gt;The first big challenge of adopting Kubernetes and Istio is not the technology but the mindset. As mentioned in the previous sections if you are deploying your application in Kubernetes you need to have answers for a lot of questions that rarely get asked and looking at the bigger picture can be a daunting experience.&lt;/p&gt;

&lt;p&gt;The benefit you gain from running an application is Kubernetes is pretty incredible. Having an elastic and highly available infrastructure frees you from worrying about a lot of common problems. Once you put all the pieces in place it is a pretty smooth ride. The same principle is valid for the infrastructure itself, creating a cluster that scales as needed is fairly straightforward if you use a cloud provider.&lt;/p&gt;

&lt;p&gt;From the perspective of developing the infrastructure itself, deploying and running a cluster is not as hard as most people may think - but not as easy as shown in a presentation. Many cloud services have their own self-managed version of Kubernetes which takes care of a whole lot of concerns you'd have running a cluster on your own.&lt;/p&gt;

&lt;p&gt;The second biggest challenge you will probably have is to keep an eye on all the moving pieces: Kubernets, Istio and many, many, many plugins. Luckily the environment around both tools is ever growing and with a pretty standard API, managing resources in a cluster is not the worst experience in the world.&lt;/p&gt;

&lt;p&gt;To give an example, right out of the box Istio will give you a good array of monitoring tools like Prometheus, Kiali, Jaegger and plugin in other services is also straightforward (like Datadog or Splunk) since most of them provide easy adapters. We then built templates for alerts and dashboards that work based off of the &lt;a href="https://istio.io/docs/reference/config/policy-and-telemetry/metrics/"&gt;standard metrics that Istio&lt;/a&gt; and &lt;a href="https://github.com/kubernetes-sigs/metrics-server"&gt;Kubernetes plugins&lt;/a&gt; provide. This way all teams had a good baseline of observability before even starting instrumenting their applications.&lt;/p&gt;

&lt;p&gt;Keeping track of all the dependencies and making sure everything is kept up to date is also another big challenge. Important security and performance updates are released constantly, some tools may not even be at 1.0+ yet. You'll need to invest time to make sure you have pretty good testing environment and be confident in your CI/CD process to release changes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Service Mesh
&lt;/h1&gt;

&lt;p&gt;Defining a service mesh is pretty hard because there is a lot to unpack, especially with Istio and the many capabilities it brings. Istio extends the Kubernetes API by creating its own resources and allowing you to define configurations ranging from terminating TLS and encrypting requests between services to traffic shaping and tracing across multiple services.&lt;/p&gt;

&lt;p&gt;This also means that when something doesn't quite work it can be really hard to find out why, which is definitely the biggest challenges with a Service Mesh. Things go wrong without much explanation and require you to look into the logs for the many components running to find out clues on what is missing, misconfigured or simply broken.&lt;/p&gt;

&lt;p&gt;To give a more concrete example let me tell about when we tried to setup automatic TLS resolution. With Istio you can &lt;a href="https://istio.io/docs/tasks/traffic-management/ingress/secure-ingress-sds/"&gt;set up TLS termination&lt;/a&gt; outside of the application, meaning the app running in the docker container uses simple HTTP but the requests are served with HTTPS. This not only simplifies the application code but would also allow us to automate the whole process by having an automated TLS &lt;a href="https://en.wikipedia.org/wiki/Public_key_infrastructure"&gt;certificate generation process&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All was great, teams could deploy their own TLS key and certificates and Istio would take care of TLS termination. Then, one day, all ingress traffic to the cluster started to fail, no request would make it to any app in the cluster. After &lt;a href="https://www.youtube.com/watch?v=AbSehcT19u0"&gt;long sessions of debugging the problem&lt;/a&gt; (from the external load balancers all the way to the VPC configuration) we finally saw some logs indicating that Istio's ingress application was not able to parse a certificate. Although we thought it had nothing to do with the issue, once we deleted the bad cert all traffic came back to normal.&lt;/p&gt;

&lt;p&gt;We then saw on a similar github issue that we could setup a default certificate to be used when the ingress pod failed to load a certificate, saving it from looping indefinitely/crashing. Once we deployed this configuration everything went back to normal and even when someone deployed a bad cert the service mesh would handle it gracefully.&lt;/p&gt;

&lt;p&gt;There are many other cases that required a digging really deep into logs, github issues and source code. If your team doesn't have a safe environment to learn, or simply doesn't want to deal with that kind of experience, I definitely recommend not using Istio or  else you'll get burned and start posting memes on twitter about how complex it is.&lt;/p&gt;

&lt;h1&gt;
  
  
  Remember to smell the flowers
&lt;/h1&gt;

&lt;p&gt;Seeing everything coming together is a really good feeling and while there are many reasons to worry and lots of things to learn, it feels great to intentionally destroy 90% of your resources and watch as everything comes back automatically and no downtime is noticed :)&lt;/p&gt;

&lt;p&gt;It may be overwhelming to get started with Kubernetes and Istio, but they also have great people doing a really good job to solve really complex problems. I am thankful for the many people dedicating their time and efforts to develop those tools.&lt;/p&gt;

&lt;p&gt;This post has been almost a brain dump from when I stopped and looked at what we've put together over an year. If you want to know more about some specific area please let me know in the comments or &lt;a href="https://twitter.com/marcosbrizeno"&gt;@MarcosBrizeno&lt;/a&gt;. I plan on writing a few other posts to talk about the architecture and components we use - and why we use them.&lt;/p&gt;

&lt;h1&gt;
  
  
  A bit of context
&lt;/h1&gt;

&lt;p&gt;I am part of a team focusing on the cloud infrastructure where application teams can deploy and run their services. It is not a DevOps team or even an infrastructure team, we try to provide the best developer experience we can so that the other teams feel empowered and are enabled to do the best job they can.&lt;/p&gt;

&lt;p&gt;Most of the services running on our platform are greenfield applications - mostly APIs, a few UIs and some background jobs. The tech stack is pretty standard, about 80% of all apps use the same language/web framework.&lt;/p&gt;

&lt;p&gt;The teams deploying applications vary in experience with microservices, continuous integration and cloud native development.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;See you space cowboy&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>istio</category>
      <category>mesh</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Optimizing docker to build and run your application</title>
      <dc:creator>Marcos Brizeno</dc:creator>
      <pubDate>Fri, 05 Oct 2018 12:25:58 +0000</pubDate>
      <link>https://forem.com/marcosx/optimizing-docker-to-build-and-run-your-application-47k4</link>
      <guid>https://forem.com/marcosx/optimizing-docker-to-build-and-run-your-application-47k4</guid>
      <description>&lt;p&gt;Docker is a great tool to for running applications without worrying about dependencies, but it can also be used to build your application. In this post I'm gonna share a nice technique I've used to build and run a web app with Docker and stopped worrying about dependencies.&lt;/p&gt;

&lt;h1&gt;
  
  
  Building vs Running
&lt;/h1&gt;

&lt;p&gt;Building an application usually requires a lot more dependencies than just running it and most languages and frameworks offer a way to build your application bundling everything you need to run it.&lt;/p&gt;

&lt;p&gt;As an example a Java application can be compiled to a single &lt;code&gt;.jar&lt;/code&gt; file, Go apps can be compiled to a binary and even applications in Ruby can be bundled in a SO package (like rpm). This makes it a lot easier to run the application, and even more so if you use Docker.&lt;/p&gt;

&lt;p&gt;Once your application is bundled, you can just copy it to a Docker image and have docker run it for you - and only worry about installing Docker itself. What about actually building the whole app in a Docker image so you don't even need to worry about the dependencies even on your machine (or on a CI server)?&lt;/p&gt;

&lt;p&gt;The main problem with building your app on the same image that will be used to run it is that this image will have to have everything required for both building and running.&lt;/p&gt;

&lt;p&gt;Every command you add in a &lt;code&gt;Dockerfile&lt;/code&gt; will add a layer to your image. Think of a Docker image as a git repository, the very first &lt;code&gt;FROM&lt;/code&gt; command is the initial commit for that repo, each command after that is like a new commit that will potentially increase the size of your repository. The more commands you have in a &lt;code&gt;Dockerfile&lt;/code&gt; the bigger your image might be.&lt;/p&gt;

&lt;p&gt;So, how about using two different images? One for building and another one for running?&lt;/p&gt;

&lt;h1&gt;
  
  
  Building and Running
&lt;/h1&gt;

&lt;p&gt;I was working on a small web app (using Java and Spring Boot) and while searching for best practices around docker I ran into &lt;a href="https://www.youtube.com/watch?v=wGz_cbtCiEA"&gt;this very useful video&lt;/a&gt;. It talks about different ways to reduce the size of your image (which is specially useful in the context of Kubernetes).&lt;/p&gt;

&lt;p&gt;So I decided to apply these techniques to build and deploy this Java/Spring Boot web app, using one image to build the &lt;code&gt;.jar&lt;/code&gt; file and another one to run it. We used gradle on this project so my first step was to use the gradle base image to build the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM gradle:jdk8 AS build-env
# Setup ARGs and ENVs
# Some RUN commands
# Copy the code
COPY --chown=gradle:gradle . .
# Some more RUN commands
# Finally, build the app
RUN ["./gradlew", "build"]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This image is actually pretty big. First of all it uses a base image that comes with a lot more stuff (comparing to the &lt;code&gt;-alpine&lt;/code&gt; alternative), because I actually need tools like &lt;code&gt;curl&lt;/code&gt; and others that I'd have to install myself if I had used a thiner version.&lt;/p&gt;

&lt;p&gt;And that's actually the point of using a build image, you don't need to worry about what's there because it will be discarded once the final image is built.&lt;/p&gt;

&lt;p&gt;Now I can define the image that will run the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM openjdk:8-alpine
COPY entrypoint.sh entrypoint.sh
COPY --from=build-env /home/gradle/build/libs/my-app-0.0.0.jar my-app.jar
ENTRYPOINT [ "sh", "entrypoint.sh" ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is a pretty thin image, it uses the &lt;code&gt;8-alpine&lt;/code&gt; version of &lt;code&gt;openjdk&lt;/code&gt;, which is much smaller and does the job well, since Java is pretty much the only runtime dependency.&lt;/p&gt;

&lt;p&gt;Both of these declaration live on the same &lt;code&gt;Dockerfile&lt;/code&gt;, note how the build image has &lt;code&gt;FROM ... AS build-env&lt;/code&gt; at the beginning. This will create a temporary image with a &lt;code&gt;build-env alias&lt;/code&gt; and since Docker only considers the last &lt;code&gt;FROM&lt;/code&gt; statement to be the actual image it will be discard afterwards. Then on the runtime image it copies from the build image with &lt;code&gt;COPY --from=build-env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And there you go, building and running an app using a single &lt;code&gt;Dockerfile&lt;/code&gt; while optimizing for each context. Using this pattern can even help simplify your CI by only having to install Docker on the agents.&lt;/p&gt;

&lt;p&gt;Thanks for taking the time to read this and hope it helps you to improve your own images :)&lt;/p&gt;

</description>
      <category>docker</category>
      <category>optimization</category>
    </item>
    <item>
      <title>Tail recursion in Elixir</title>
      <dc:creator>Marcos Brizeno</dc:creator>
      <pubDate>Sat, 04 Aug 2018 20:06:14 +0000</pubDate>
      <link>https://forem.com/marcosx/tail-recursion-in-elixir-1o5p</link>
      <guid>https://forem.com/marcosx/tail-recursion-in-elixir-1o5p</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1s6rjwku98btrqxgh655.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1s6rjwku98btrqxgh655.jpg" alt="A pendant and a wall with wood pieces on the background"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You've probably heard (and written) some recursive functions/methods before. Chances are you've also heard that recursive functions might be more expensive when compared to a non-recursive alternative.&lt;/p&gt;

&lt;p&gt;Let's see what is probably the simples example of a recursive function, the factorial implementation. Here we define two clauses of &lt;code&gt;Factorial.recursive_factorial/1&lt;/code&gt;, on for &lt;code&gt;0&lt;/code&gt; (which returns &lt;code&gt;1&lt;/code&gt;) and another for any other value:&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;Factorial&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;recursive_factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;recursive_factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;recursive_factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;p&gt;On each call of &lt;code&gt;recursive_factorial(n)&lt;/code&gt; we multiply &lt;code&gt;n&lt;/code&gt; by the result of &lt;code&gt;recursive_factorial(n-1)&lt;/code&gt; (which is a recursive call until &lt;code&gt;n&lt;/code&gt; reaches &lt;code&gt;0&lt;/code&gt;). On every step we need to keep the current value of &lt;code&gt;n&lt;/code&gt; so we can multiply it once &lt;code&gt;recursive_factorial(n-1)&lt;/code&gt; is returned.&lt;/p&gt;

&lt;p&gt;This is why recursive calls are usually considered to be more expensive (specially in terms of space), each call requires the stack to be saved until the result comes back. Saving a stack, even if it is just that &lt;code&gt;n&lt;/code&gt; might start causing trouble when the number gets too high (say &lt;code&gt;500_000&lt;/code&gt; or more, depending on where you're running it).&lt;/p&gt;

&lt;p&gt;But there is something we can do to make it better and as performant as the non recursive alternatives&lt;/p&gt;

&lt;h2&gt;
  
  
  Tail Recursion
&lt;/h2&gt;

&lt;p&gt;Take a look at this other implementation and compare it to the previous one:&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;Factorial&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;tail_recursive_factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tail_recursive_factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;tail_recursive_factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;
  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;tail_recursive_factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tail_recursive_factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;n&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;p&gt;The first call to &lt;code&gt;Factorial.tail_recursive_factorial/1&lt;/code&gt; starts the process by calling the private &lt;code&gt;Factorial.tail_recursive_factorial/2&lt;/code&gt; which does the recursive process.&lt;/p&gt;

&lt;p&gt;Notice that the multiplication is now passed to the recursive call using the second argument. This means that there is no need to store the function stack for each call!&lt;/p&gt;

&lt;p&gt;Each call now has everything it needs and the stack can be discarded as soon as the recursive call starts. The end clause here is when &lt;code&gt;n&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt; and it just returns the value on &lt;code&gt;acc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When a recursive function doesn't need to store any temporary value to be used after the recursive call, it is considered a Tail Recursive function. Let's check a more interesting problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 'Strain' exercise on Exercism
&lt;/h2&gt;

&lt;p&gt;On exercism.io there is a nice little exercise where you're asked to implement two functions, &lt;code&gt;keep&lt;/code&gt; and &lt;code&gt;discard&lt;/code&gt;. Given a &lt;code&gt;list&lt;/code&gt; of items and a function &lt;code&gt;fun&lt;/code&gt;, &lt;code&gt;keep&lt;/code&gt; will return the list of items where &lt;code&gt;fun&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt; and &lt;code&gt;discard&lt;/code&gt; will return the list of items where &lt;code&gt;fun&lt;/code&gt; returns &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Me and some friends got together to solve this and our initial implementation of &lt;code&gt;keep&lt;/code&gt; was to execute &lt;code&gt;fun&lt;/code&gt; on the &lt;code&gt;head&lt;/code&gt; of the list and if it is &lt;code&gt;true&lt;/code&gt; return a list with the the &lt;code&gt;head&lt;/code&gt; and then recurse on &lt;code&gt;tail&lt;/code&gt;, if not then just call again ignoring the &lt;code&gt;head&lt;/code&gt; of the list:&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;def&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt; &lt;span class="n"&gt;_fun&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&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;def&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&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;keep_if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&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;defp&lt;/span&gt; &lt;span class="n"&gt;keep_if&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&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;defp&lt;/span&gt; &lt;span class="n"&gt;keep_if&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;false&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;keep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&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;p&gt;The main problem here is that for each call where &lt;code&gt;fun&lt;/code&gt; is true we need to save the value stored on &lt;code&gt;head&lt;/code&gt; and after the recursive call finishes, the return has to be appended to a list containing &lt;code&gt;head&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the test scenarios we had, this wasn't a big issue, but we wanted to go a bit further and think about how to make this a tail recursive function.&lt;/p&gt;

&lt;p&gt;Our optimization was similar to what we did for &lt;code&gt;Factorial.tail_recursive_factorial/1&lt;/code&gt;, we create an accumulator argument and send it on each call instead of waiting to get the result back. Here is how it ended up looking like:&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;Strain&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&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;keep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="n"&gt;fun&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;def&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt; &lt;span class="n"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_fun&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;filtered&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;

 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_tail&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&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;keep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&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;defp&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;true&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;keep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filtered&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;fun&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;defp&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;_head&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;false&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;keep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fun&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;Another nice exercise to try and apply tail recursive optimization is the 'List Operations' one where you're asked to implement basic functions that we usually take for granted, like &lt;code&gt;each&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;Recursive functions are quite common in functional languages, most of them don't even have loops, so learning about tail recursion and practicing how to implement it is a good investment :)&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>recursion</category>
      <category>tailrecursion</category>
    </item>
    <item>
      <title>Don't let duplication mislead you</title>
      <dc:creator>Marcos Brizeno</dc:creator>
      <pubDate>Thu, 09 Nov 2017 14:00:11 +0000</pubDate>
      <link>https://forem.com/marcosx/dont-let-duplication-mislead-you-e90</link>
      <guid>https://forem.com/marcosx/dont-let-duplication-mislead-you-e90</guid>
      <description>

&lt;p&gt;In this article I'm going to tell you about how I started to understand what software design principles mean and hopefully it will give you some insights on how to put them in practice.&lt;/p&gt;

&lt;h1&gt;
  
  
  Duplication is better than the wrong abstraction
&lt;/h1&gt;

&lt;p&gt;Sandi Metz is one of my favorite authors, every time I read something from her it changes how I think about improving my code. Something that I kept thinking about lately was this phrase: "Duplication is better than the wrong abstraction".&lt;/p&gt;

&lt;p&gt;The first language I used professionally was Ruby and the Ruby community is well known for making programming fun and creating readable code, so I got into reading a lot of books/articles on how to write good code.&lt;/p&gt;

&lt;p&gt;One of the first things I learned was to name things, but since naming is a quite subjective topic, the second thing I learned really stuck with me: Don't repeat yourself!&lt;/p&gt;

&lt;p&gt;The famous DRY principle taught me that duplication is bad for maintenance, so try and reduce it as much as you can. When I heard "Duplication is better than the wrong abstraction" my brain crashed. And I had to reboot it.&lt;/p&gt;

&lt;h1&gt;
  
  
  What do I not know about this code?
&lt;/h1&gt;

&lt;p&gt;It was actually "easy" to understand why duplication is better than the wrong abstraction, my friend Luciano Ramalho said "it's better to walk than to take the wrong bus" and I think that is a pretty good metaphor. But it was only when I faced my self with a duplication and resisted the urge to extract a new method that I realized why duplication is better than the wrong abstraction.&lt;/p&gt;

&lt;p&gt;I was taking a look at a code I had just written following the Shameless Green approach (from &lt;a href="https://www.sandimetz.com/99bottles/"&gt;99 Bottle of OOP&lt;/a&gt; - amazing book by Sandi Metz and Katrina Owen by the way) and found a easy to strike duplication:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_successful_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;leave_id: &lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;leave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;status: &lt;/span&gt;&lt;span class="no"&gt;SUCCESS&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;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_failed_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;leave_id: &lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;leave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;status: &lt;/span&gt;&lt;span class="no"&gt;FAILED&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;p&gt;Instead of just extracting to a method and passing stuff as parameter I thought to myself: "what do I not know about this code?". And then it hit me: duplication is not about two similar pieces of code, it's about an abstraction that is yet to exist.&lt;/p&gt;

&lt;p&gt;The real problem is not just the duplication, the event object is completely exposed! It gets passed as a parameter and then completely shattered to make up this hash object that is then passed to the create method.&lt;/p&gt;

&lt;h1&gt;
  
  
  Other code smells might help
&lt;/h1&gt;

&lt;p&gt;What I didn't know about this code, and in hindsight it looks kinda obvious, was that the event object should be responsible for building that data hash.&lt;/p&gt;

&lt;p&gt;When an object cares more about receiving parameters than itself, it usually means that a feature is misplaced - a code smell known as Feature Envy. To remove the original duplication what I ended up doing was creating a new method on event to return the data hash and then just calling it instead of exposing the object.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_successful_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;status: &lt;/span&gt;&lt;span class="no"&gt;SUCCESS&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;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_failed_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;status: &lt;/span&gt;&lt;span class="no"&gt;FAILED&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;p&gt;&lt;em&gt;I know data is a bad method name :/&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Refactoring with confidence
&lt;/h1&gt;

&lt;p&gt;I got into the habit of reading the code and identifying smells first, instead of just diving into the code to make improvements, and I think it really helped me refactor with confidence.&lt;/p&gt;

&lt;p&gt;There are many automated tools that help identify code smells and I try to use them, but nothing beats intuition! Invest some time reading books on refactoring, code smells, design patterns and specially reading code.&lt;/p&gt;

&lt;p&gt;Take some time in the morning to just read through your code, resist the urge to make changes though, focus on how the pieces fit together instead. This way you'll build the foundations of your intuition and understanding what all those design principles really mean.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post is a longer version of &lt;a href="https://twitter.com/MarcosBrizeno/status/918486735784464384"&gt;this twitter thread&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;


</description>
      <category>design</category>
      <category>refactoring</category>
      <category>codesmells</category>
    </item>
    <item>
      <title>The Godclass</title>
      <dc:creator>Marcos Brizeno</dc:creator>
      <pubDate>Thu, 11 May 2017 12:44:54 +0000</pubDate>
      <link>https://forem.com/marcosx/the-godclass</link>
      <guid>https://forem.com/marcosx/the-godclass</guid>
      <description>

&lt;p&gt;Alright, you got assigned to a team that is working on this - quite old - project and you're really looking forward into getting your hands dirty with some legacy code.&lt;/p&gt;

&lt;p&gt;After a brief technical onboarding on the whiteboard by the techlead you go with her to a pairing station and start setting up the local environment for your first day of work. After exploring the code a bit you get to the &lt;code&gt;Listing&lt;/code&gt; class and, as you scroll the never ending file, you already start hating this &lt;strong&gt;Godclass&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And, as you wonder how that class got this big, you start imagining how the first weeks of work on this project were. Maybe after a discussion with some "business people" the team figured it would be necessary to have the &lt;code&gt;Listing&lt;/code&gt; class. From there it was easy to just add more and more stuff to it. This is a auction system after all, so it makes sense that the central element is a &lt;code&gt;listing&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As you read the methods and test cases, it all start to make sense. Since a listing can be in many states - like draft, preview, published, ... - you need to control all of that. And each state enables different behavior, so sure there are quite some &lt;code&gt;if&lt;/code&gt;s spread around the code. A listing also contains a lot of information, so there is definitely a lot of fields in the object. But hey, at least it has a lot of testing!&lt;/p&gt;

&lt;p&gt;As you see yourself starting to agree that all this messy code actually makes sense, you stop and slap yourself in the face (but that's all in your head, so don't worry, no one saw it). No class, no matter how important, should be this big and violate the Single Responsibility Principle like that!&lt;/p&gt;

&lt;h2&gt;
  
  
  A class becomes a Godclass
&lt;/h2&gt;

&lt;p&gt;Of course, right? No one creates a Godclass from day one, as the old saying goes: it takes a village  to raise a Godclass.&lt;/p&gt;

&lt;p&gt;A class turns into a Godclass because it just makes sense! Think about a domain and what would be a good candidate for a Godclass: an e-commerce will probably have a &lt;code&gt;Product&lt;/code&gt;, an auction system will have a &lt;code&gt;Listing&lt;/code&gt;, and is very likely that an aviation application would have a &lt;code&gt;Flight&lt;/code&gt; and a &lt;code&gt;Passenger&lt;/code&gt;. It just makes sense.&lt;/p&gt;

&lt;p&gt;Usually a Godclass will capture the essence of your domain, like a &lt;code&gt;Product&lt;/code&gt; in an e-commerce, and it will probably become a central point of the design. Everything in an e-commerce platform revolves around people buying products, so the way you create a product, the way you show them and how you handle inventory is key.&lt;/p&gt;

&lt;p&gt;Are we all destined to create a Godclass? Is it just a matter of time?&lt;/p&gt;

&lt;h2&gt;
  
  
  What if there's no Godclass?
&lt;/h2&gt;

&lt;p&gt;If you work with an old enough system, you probably have a Godclass hanging around on your codebase (hopefully you'll have only one).&lt;/p&gt;

&lt;p&gt;Now think for a minute, what if there was on &lt;code&gt;Listing&lt;/code&gt; class on an auction application? How would you go about modeling the domain without using this name? How would you group the behavior for publishing a listing and handling bids without using the word "listing"?&lt;/p&gt;

&lt;p&gt;Think for a minute. Ok, just a few seconds will do, I know we're all busy these days.&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;It's hard right? It just makes sense to have a &lt;code&gt;Listing&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Not using a name that is central to your domain is probably a bad idea, since this name will capture the essence of your domain. But the exercise of completely eradicate the Godclass and banish the name from the vocabulary might be interesting.&lt;/p&gt;

&lt;p&gt;If you don't have a Godclass, all that behavior will have to be split among other classes right? I mean, you'll have to support the same features and use cases, so the code will have to be there, somewhere. Will a new Godclass appear? Could some behavior be absorbed by an existing class? Can you identify what can be split in other classes? How those classes will look like?&lt;/p&gt;

&lt;p&gt;Doing this exercise will provide good hints of how you could reduce the power of the Godclass  and, potentially, improve the design of your application. It will also show how well you know your domain and how sharp your modeling skills are.&lt;/p&gt;

&lt;p&gt;Don't forget that there's much more to software development than just writing code :)&lt;/p&gt;


</description>
      <category>softwaredesign</category>
    </item>
    <item>
      <title>Hi, I'm Marcos Brizeno</title>
      <dc:creator>Marcos Brizeno</dc:creator>
      <pubDate>Thu, 11 May 2017 11:36:45 +0000</pubDate>
      <link>https://forem.com/marcosx/hi-im-marcos-brizeno</link>
      <guid>https://forem.com/marcosx/hi-im-marcos-brizeno</guid>
      <description>&lt;p&gt;I have been coding for 5 years.&lt;/p&gt;

&lt;p&gt;You can find me on GitHub as &lt;a href="https://github.com/MarcosX" rel="noopener noreferrer"&gt;MarcosX&lt;/a&gt; and on Twitter as &lt;a href="https://twitter.com/marcosbrizeno" rel="noopener noreferrer"&gt;@marcosbrizeno&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in Belo Horizonte working for ThoughtWorks.&lt;/p&gt;

&lt;p&gt;I mostly program in these languages: ["ruby", "javascript", "python", "java"] and am currently learning more about elixir and crystal.&lt;/p&gt;

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

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