<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://fcastellanos.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://fcastellanos.io/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-10-26T12:23:28-07:00</updated><id>https://fcastellanos.io/feed.xml</id><title type="html">Fernando’s Blog</title><subtitle>Notes on software engineering, Ruby, Rails, testing, mobile and whatever I&apos;m building lately.</subtitle><author><name>Fernando Castellanos</name></author><entry><title type="html">From Prompts to Skills: How I Taught Claude Code My Workflow</title><link href="https://fcastellanos.io/2026/10/24/from-prompts-to-skills/" rel="alternate" type="text/html" title="From Prompts to Skills: How I Taught Claude Code My Workflow" /><published>2026-10-24T09:00:00-07:00</published><updated>2026-10-24T09:00:00-07:00</updated><id>https://fcastellanos.io/2026/10/24/from-prompts-to-skills</id><content type="html" xml:base="https://fcastellanos.io/2026/10/24/from-prompts-to-skills/"><![CDATA[<p>For months I used Claude Code the way most people do: open a session, explain what I wanted, watch it work, correct it, and explain the same things again the next day. Then I turned that repeated explaining into a few small Markdown files called skills. Now “work on 131” is a complete instruction, and this post is about how I got there.</p>

<h2 id="the-project">The project</h2>

<p>I’m building a school administration platform as a side project: a Rails app, a React Native (Expo) mobile client, and a GitHub Projects board that tracks everything as issues. I’m the only developer, so the board is my memory. Every bug, feature, and idea becomes a ticket that moves from Backlog to Ready, In progress, In review, and Done.</p>

<p>Claude Code does most of the typing now. My job is deciding what to build and reviewing what comes back.</p>

<h2 id="before-the-same-prompt-every-time">Before: the same prompt, every time</h2>

<p>My early sessions all started with some version of this:</p>

<blockquote>
  <p>Read issue 124, including the comments. Look at the code it mentions. Tell me your plan before changing anything. Then create a branch named after the issue, move the ticket to In progress, implement it, run the tests and RuboCop, open a PR that says “Fixes #124”, and move the ticket to In review. Don’t merge.</p>
</blockquote>

<p>It worked, but only if I remembered every line. When I forgot one, I got a PR without the <code class="language-plaintext highlighter-rouge">Fixes</code> line, a branch cut from whatever branch I happened to be on, or a ticket still sitting in Ready when the work was done. Each mistake was small, but I kept fixing the same ones over and over.</p>

<p>The fix for most of them was the same: stop typing the procedure, and write it down once where the agent can find it.</p>

<h2 id="what-a-skill-is">What a skill is</h2>

<p>A skill is a folder in your repo with a <code class="language-plaintext highlighter-rouge">SKILL.md</code> file inside:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.claude/skills/
  work-ticket/SKILL.md
  check-ticket/SKILL.md
  create-ticket/SKILL.md
</code></pre></div></div>

<p>The file starts with a short front matter block. The <code class="language-plaintext highlighter-rouge">description</code> matters most, because Claude Code reads it to decide when the skill applies:</p>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">work-ticket</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">Pick up a ticket from the School Admin board by issue number,</span>
  <span class="s">issue URL, or board link. Assesses the ticket, confirms a plan with the</span>
  <span class="s">user, moves it to "In progress", creates a numbered branch, implements</span>
  <span class="s">the work, and opens a PR for review.</span>
<span class="nn">---</span>
</code></pre></div></div>

<p>Below that is plain Markdown, with numbered steps and the exact commands I’d otherwise type. There’s no framework or plugin to install. Because the skill lives in the repo, it gets versioned and reviewed like any other code.</p>

<h2 id="the-first-skill-work-ticket">The first skill: work-ticket</h2>

<p>I wrote <code class="language-plaintext highlighter-rouge">work-ticket</code> at the end of July. It was mostly my old prompt, cleaned up and split into steps:</p>

<ol>
  <li>Turn the reference into an issue number (a bare <code class="language-plaintext highlighter-rouge">124</code>, an issue URL, or a board link).</li>
  <li>Read the ticket, <em>including the comments</em>, since that’s where scope changes live.</li>
  <li>Look into the code.</li>
  <li>Write an assessment and a step-by-step plan.</li>
  <li><strong>Stop and ask me to confirm.</strong> Nothing changes before I say yes.</li>
  <li>Move the board item to In progress.</li>
  <li>Create a branch named <code class="language-plaintext highlighter-rouge">&lt;number&gt;-&lt;short-description&gt;</code>.</li>
  <li>Implement.</li>
  <li>Run the tests and RuboCop.</li>
  <li>Open the PR with <code class="language-plaintext highlighter-rouge">Fixes #&lt;number&gt;</code> and move the item to In review.</li>
</ol>

<p>It ends with two guardrails I care about more than any single step:</p>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gu">## Guardrails</span>
<span class="p">-</span> Never push directly to <span class="sb">`main`</span> and never merge the PR yourself.
<span class="p">-</span> If the plan needs to change significantly mid-implementation, pause
  and re-check with the user before continuing.
</code></pre></div></div>

<p>After that, my prompts got very short. “Work on 131” was enough.</p>

<h2 id="skills-grow-from-corrections">Skills grow from corrections</h2>

<p>What I didn’t expect was how the skills would change over time. Almost every edit started as a correction I made during a session, which I then wrote into the file so I’d never have to make it again. From the git history:</p>

<ul>
  <li><strong>Same night:</strong> “Check the current branch before creating a new one,” so it never branches off something I’m halfway through.</li>
  <li><strong>Same night:</strong> a merge step, but only after I explicitly say the PR is reviewed and approved.</li>
  <li><strong>Three weeks later:</strong> “Check CI before merging.” My “yes, merge it” shouldn’t count if a check went red after I said it.</li>
  <li><strong>September:</strong> size the investigation to the ticket. For a one-file fix, read the file directly instead of starting a search subagent, and run only the tests you touched unless the change is broad.</li>
  <li><strong>Late September:</strong> the board passed 500 items, and the way the skill looked up a ticket’s board entry quietly stopped working. The fix was to ask the issue for its board item instead of listing the whole board.</li>
</ul>

<p>None of these were planned. Each one was a moment where I thought “I’ve told it this before,” and the right response was to edit the file instead of the prompt.</p>

<h2 id="splitting-the-job-create-check-work">Splitting the job: create, check, work</h2>

<p>Once <code class="language-plaintext highlighter-rouge">work-ticket</code> was solid, the same pattern showed up at the other end of the board. Tickets I’d filed months earlier were often stale. The bug had already been fixed, or the file the ticket mentioned no longer existed.</p>

<p>So I added <code class="language-plaintext highlighter-rouge">check-ticket</code>. It reads a ticket, investigates whether it’s still true, and does one of two things:</p>

<ul>
  <li>If it’s no longer valid, it posts a comment with the evidence (a file and line, a merged PR, a duplicate issue) and <em>asks</em> whether to close it.</li>
  <li>If it’s still valid but missing something, like repro steps or acceptance criteria, it comments with exactly what’s missing and offers to hand off to <code class="language-plaintext highlighter-rouge">work-ticket</code>.</li>
</ul>

<p>Then I added <code class="language-plaintext highlighter-rouge">create-ticket</code>, which turns one sentence into an issue on the board in Backlog. It deliberately does very little itself. Its last step is to call <code class="language-plaintext highlighter-rouge">check-ticket</code> on the new issue, so the investigation logic lives in one place instead of two.</p>

<p>The result is a pipeline that matches how I already thought about the board:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>one sentence ──&gt; create-ticket ──&gt; check-ticket ──&gt; work-ticket ──&gt; PR
                  (file it)        (is it real?    (plan, branch,
                                    what's missing?) build, test)
</code></pre></div></div>

<p>Here’s a real run. I typed:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/create-ticket Ability to delete cancelled events from calendar
</code></pre></div></div>

<p>A minute later I had issue #1073 in Backlog with a follow-up comment from <code class="language-plaintext highlighter-rouge">check-ticket</code> raising three things to settle first: only allow deleting a meeting that’s already cancelled, add the first action to the cancelled-meeting card, and reuse the refresh pattern from the PR that had just landed so we wouldn’t reintroduce a stale-calendar bug. I answered the three questions in one message, and it added my decisions to the ticket.</p>

<h2 id="the-mobile-app-got-its-own-copy">The mobile app got its own copy</h2>

<p>The mobile repo has the same three skills, adapted to its own board and with one important addition. The mobile app is a client for the Rails API, so before filing a ticket, <code class="language-plaintext highlighter-rouge">create-ticket</code> checks whether the request can actually be built against the existing API contract:</p>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code>If backend work looks needed, stop and tell the user what appears to be
missing and why (cite the specific endpoint/field gap), then ask for
explicit confirmation on how to proceed. Do not create the issue until
they confirm.
</code></pre></div></div>

<p>That one paragraph has saved me from filing mobile tickets that couldn’t be built yet.</p>

<h2 id="what-ive-learned">What I’ve learned</h2>

<p><strong>Start with the prompt you keep retyping.</strong> My first skill was a cleaned-up copy of a prompt I already used every day. You don’t need to design anything up front.</p>

<p><strong>Edit the skill, not the session.</strong> When the agent gets something wrong in a way it’ll get wrong again, fix it in the file. Corrections in chat disappear when the session ends; corrections in the file stay.</p>

<p><strong>Keep each skill small and hand off.</strong> <code class="language-plaintext highlighter-rouge">create-ticket</code> doesn’t investigate, it calls <code class="language-plaintext highlighter-rouge">check-ticket</code>. Small skills that call each other are easier to fix than one big one.</p>

<p><strong>Write guardrails as rules, not suggestions.</strong> “Never merge without explicit confirmation” and “never close an issue based only on this skill’s assessment” are the lines that let me trust the rest. The agent handles the steps; the irreversible decisions stay with me.</p>

<p><strong>Put the commands in.</strong> Exact <code class="language-plaintext highlighter-rouge">gh</code> commands with the real project number make the skill both reliable and fast. The agent doesn’t have to rediscover how my board works every time.</p>

<p>I’ve since added skills for pre-merge reviews, visual mockups, and keeping Dependabot PRs moving, and I’ll write about some of those next. They all started the same way, as a prompt I was tired of typing.</p>]]></content><author><name>Fernando Castellanos</name></author><category term="ai" /><category term="claude-code" /><category term="workflow" /><category term="github" /><summary type="html"><![CDATA[For months I used Claude Code the way most people do: open a session, explain what I wanted, watch it work, correct it, and explain the same things again the next day. Then I turned that repeated explaining into a few small Markdown files called skills. Now “work on 131” is a complete instruction, and this post is about how I got there.]]></summary></entry><entry><title type="html">Configure Sidekiq With Rails</title><link href="https://fcastellanos.io/2020/11/23/configure-sidekiq-with-rails/" rel="alternate" type="text/html" title="Configure Sidekiq With Rails" /><published>2020-11-23T11:29:47-08:00</published><updated>2020-11-23T11:29:47-08:00</updated><id>https://fcastellanos.io/2020/11/23/configure-sidekiq-with-rails</id><content type="html" xml:base="https://fcastellanos.io/2020/11/23/configure-sidekiq-with-rails/"><![CDATA[<p>According to their website Sidekiq is an efficient background processing for Ruby. It says Ruby but you can also use it in Rails and it even has a nice web UI where you can see some stats.</p>

<p>This blog post will be a brief overview of how to configure Sidekiq in Rails.</p>

<p>The very first thing is to add the gem in the <code class="language-plaintext highlighter-rouge">Gemfile</code> like this</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">gem</span> <span class="s1">'sidekiq'</span><span class="p">,</span> <span class="s1">'~&gt; 6.1.0'</span>
</code></pre></div></div>

<p>and run <code class="language-plaintext highlighter-rouge">bundle install</code></p>

<p>Now let’s assume that we’re working on a Blog project where we have a <code class="language-plaintext highlighter-rouge">User</code>, <code class="language-plaintext highlighter-rouge">Post</code>, and <code class="language-plaintext highlighter-rouge">Comment</code> models like this…</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">User</span> <span class="o">&lt;</span> <span class="no">ApplicationRecord</span>
    <span class="n">has_many</span> <span class="ss">:posts</span>
<span class="k">end</span>

<span class="k">class</span> <span class="nc">Post</span> <span class="o">&lt;</span> <span class="no">ApplicationRecord</span>
  <span class="n">belongs_to</span> <span class="ss">:user</span>
  <span class="n">has_many</span> <span class="ss">:comments</span>
<span class="k">end</span>

<span class="k">class</span> <span class="nc">Comment</span> <span class="o">&lt;</span> <span class="no">ApplicationRecord</span>
  <span class="n">belongs_to</span> <span class="ss">:post</span>
  <span class="n">belongs_to</span> <span class="ss">:user</span>
<span class="k">end</span>
</code></pre></div></div>

<p>And for whatever reason we want to create a background job that creates a random comment on a random post… the cool thing about Rails and background jobs is that Rails has the <code class="language-plaintext highlighter-rouge">ActiveJob</code> framework that is some sort of interface for background jobs so you can switch the backend to whatever you want.</p>

<p>So in order to create a background job in Rails for Sidekiq we first need to configure sidekiq and since in this case I’m just going to test it in development I’ll go ahead and open <code class="language-plaintext highlighter-rouge">config/environments/development.rb</code> and add the below lines in stating that we want to use sidekiq as the backend for background jobs and the queue name prefix…</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">config</span><span class="p">.</span><span class="nf">active_job</span><span class="p">.</span><span class="nf">queue_adapter</span> <span class="o">=</span> <span class="ss">:sidekiq</span>
<span class="n">config</span><span class="p">.</span><span class="nf">active_job</span><span class="p">.</span><span class="nf">queue_name_prefix</span> <span class="o">=</span> <span class="s2">"sidekiq_example_development"</span>
</code></pre></div></div>

<p>Next we configure an initializer for Sidekiq in <code class="language-plaintext highlighter-rouge">config/initializers/sidekiq.rb</code></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">Sidekiq</span><span class="p">.</span><span class="nf">configure_server</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
    <span class="n">config</span><span class="p">.</span><span class="nf">redis</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">url: </span><span class="s1">'redis://localhost:6379/0'</span> <span class="p">}</span>
<span class="k">end</span>
  
<span class="no">Sidekiq</span><span class="p">.</span><span class="nf">configure_client</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
    <span class="n">config</span><span class="p">.</span><span class="nf">redis</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">url: </span><span class="s1">'redis://localhost:6379/0'</span> <span class="p">}</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Here’s where we configure Sidekiq’s client and server pointing to redis, in my case it’s a local redis server using Redis.app</p>

<p>The final step in the configuration is to specify Sidekiq what queues from Redis to pick up, we do that by creating a file in <code class="language-plaintext highlighter-rouge">config/sidekiq.yml</code></p>

<div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">:queues</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="s">sidekiq_example_development_default</span>
  <span class="pi">-</span> <span class="s">sidekiq_example_production_default</span>
</code></pre></div></div>

<p>And that’s pretty much it on the configuration side unless you want to configure the UI which I’ll show you how in <code class="language-plaintext highlighter-rouge">config/routes.rb</code></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">Rails</span><span class="p">.</span><span class="nf">application</span><span class="p">.</span><span class="nf">routes</span><span class="p">.</span><span class="nf">draw</span> <span class="k">do</span>
  <span class="c1"># For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html</span>
  <span class="c1"># ...</span>
  <span class="nb">require</span> <span class="s1">'sidekiq/web'</span>
  <span class="n">mount</span> <span class="no">Sidekiq</span><span class="o">::</span><span class="no">Web</span> <span class="o">=&gt;</span> <span class="s1">'/sidekiq'</span>
<span class="k">end</span>
</code></pre></div></div>

<p>It’s as simple as that not too bad, now let’s go ahead and create a Sidekiq background job through Rails via <code class="language-plaintext highlighter-rouge">ActiveJob</code>, in the terminal we type…</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ rails g job generate_random_comment
</code></pre></div></div>

<p>This creates a file <code class="language-plaintext highlighter-rouge">app/jobs/generate_random_comment_job.rb</code></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">GenerateRandomCommentJob</span> <span class="o">&lt;</span> <span class="no">ApplicationJob</span>
  <span class="n">queue_as</span> <span class="ss">:default</span>

  <span class="k">def</span> <span class="nf">perform</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
    <span class="c1"># Do something later</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Now let’s do something not efficient to do in the background like creating a random comment on a random post and for that we’ll use the <code class="language-plaintext highlighter-rouge">Faker</code> gem</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Inside Gemfile</span>

<span class="n">gem</span> <span class="s1">'faker'</span>
</code></pre></div></div>

<p>And now inside <code class="language-plaintext highlighter-rouge">app/jobs/generate_random_comment_job.rb</code></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">GenerateRandomCommentJob</span> <span class="o">&lt;</span> <span class="no">ApplicationJob</span>
  <span class="n">queue_as</span> <span class="ss">:default</span>

  <span class="k">def</span> <span class="nf">perform</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
    <span class="c1"># Fetching a random user</span>
    <span class="n">user</span> <span class="o">=</span> <span class="no">User</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span>
      <span class="no">User</span><span class="p">.</span><span class="nf">pluck</span><span class="p">(</span><span class="ss">:id</span><span class="p">).</span><span class="nf">sample</span>
    <span class="p">)</span>

    <span class="c1"># Fetching a random post from user</span>
    <span class="n">post</span> <span class="o">=</span> <span class="no">Post</span><span class="p">.</span><span class="nf">find</span><span class="p">(</span>
      <span class="n">user</span><span class="p">.</span><span class="nf">posts</span><span class="p">.</span><span class="nf">pluck</span><span class="p">(</span><span class="ss">:id</span><span class="p">).</span><span class="nf">sample</span>
    <span class="p">)</span>

    <span class="c1"># Creating a random comment with Faker</span>
    <span class="n">post</span><span class="p">.</span><span class="nf">comments</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span>
      <span class="ss">title: </span><span class="no">Faker</span><span class="o">::</span><span class="no">Lorem</span><span class="p">.</span><span class="nf">word</span><span class="p">,</span>
      <span class="ss">content: </span><span class="no">Faker</span><span class="o">::</span><span class="no">Lorem</span><span class="p">.</span><span class="nf">sentence</span><span class="p">,</span>
      <span class="ss">user: </span><span class="n">user</span>
    <span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Right before we run the background job we need to make sure both Redis and Sidekiq are running, in order to run Sidekiq we go to the terminal run</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sidekiq
</code></pre></div></div>

<p>And you should see this nice graphic</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>               m,
               `$b
          .ss,  $$:         .,d$
          `$$P,d$P'    .,md$P"'
           ,$$$$$b/md$$$P^'
         .d$$$$$$/$$$P'
         $$^' `"/$$$'       ____  _     _      _    _
         $:     ,$$:       / ___|(_) __| | ___| | _(_) __ _
         `b     :$$        \___ \| |/ _` |/ _ \ |/ / |/ _` |
                $$:         ___) | | (_| |  __/   &lt;| | (_| |
                $$         |____/|_|\__,_|\___|_|\_\_|\__, |
              .d$$                                       |_|
      
</code></pre></div></div>

<p>Now let’s take the background job for a spin in the rails console <code class="language-plaintext highlighter-rouge">$ rails c</code> and type this…</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; GenerateRandomCommentJob.perform_later
Enqueued GenerateRandomCommentJob (Job ID: f2a594a9-9b9f-4900-8f32-a07d030b04e8) to Sidekiq(sidekiq_example_development_default)
 =&gt; #&lt;GenerateRandomCommentJob:0x00007f9d88287788 @arguments=[], @job_id="f2a594a9-9b9f-4900-8f32-a07d030b04e8", @queue_name="sidekiq_example_development_default", @priority=nil, @executions=0, @exception_executions={}, @provider_job_id="8ab54cb7e77b2d218bec63e2"&gt;
</code></pre></div></div>

<p>And if you have the Rails server running <code class="language-plaintext highlighter-rouge">$ rails s</code> and go to <code class="language-plaintext highlighter-rouge">http://localhost:3000/sidekiq/queues</code> you should see something like this</p>

<p><img src="/assets/img/configure-sidekick/image-1.png" alt="Example image" /></p>

<p>Awesome, this means that we have successfully ran our background job with Sidekiq through Redis inside a Rails app, now let’s make things a bit more fun running the background job multiple times to see a bit better Sidekiq in action.</p>

<p>Let’s run the background job 100 times through the Rails console</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&gt;</span> <span class="mi">100</span><span class="p">.</span><span class="nf">times</span> <span class="p">{</span> <span class="no">GenerateRandomCommentJob</span><span class="p">.</span><span class="nf">perform_later</span> <span class="p">}</span>
</code></pre></div></div>

<p>And see what happens in the web UI</p>

<p><img src="/assets/img/configure-sidekick/image-2.png" alt="Example image" /></p>

<p>Awesome now we have a basic configuration for Redis + Sidekiq + Rails running locally :)</p>

<p>Happy coding! if you have any questions please let me know in twitter at <a href="https://twitter.com/fcastellanos">@fcastellanos</a>.</p>]]></content><author><name>Fernando Castellanos</name></author><category term="ruby" /><category term="background-jobs" /><category term="redis" /><summary type="html"><![CDATA[According to their website Sidekiq is an efficient background processing for Ruby. It says Ruby but you can also use it in Rails and it even has a nice web UI where you can see some stats.]]></summary></entry><entry><title type="html">Minitest Custom Assertions</title><link href="https://fcastellanos.io/2020/11/19/minitest-custom-assertions/" rel="alternate" type="text/html" title="Minitest Custom Assertions" /><published>2020-11-19T10:17:33-08:00</published><updated>2020-11-19T10:17:33-08:00</updated><id>https://fcastellanos.io/2020/11/19/minitest-custom-assertions</id><content type="html" xml:base="https://fcastellanos.io/2020/11/19/minitest-custom-assertions/"><![CDATA[<p>Since I discovered the world of testing and TDD I’ve loved the philosophy behind it and the safety net that it brings. My first interaction with testing was with Ruby on Rails specifically with RSpec, but I’ll admit it, understanding and getting used to testing is not easy but RSpec did a very good job at making it easier and in combination with shoulda matchers makes tests wonderfully easy to read. On the frontend we have Cucumber which is like reading a story but can can take a lot of time and effort to build and maintain, which is one of the reasons why the Steak testing framework was built because it was just ruby, and with this idea I am writing this blog post to talk about why I’m starting to love minitest.</p>

<p>Minitest is a small, simple and fast testing framework that not only facilitates testing, TDD, etc, but also provides mocking and benchmarking, and on the comparison before between Cucumber and Steak, RSpec is a DSL while Minitest is just Ruby which not only will it be faster but also you can customize however you want.</p>

<p>Minitest is also part of the standard library meaning that you don’t have to add external libraries which also means that it’s available for you to use in Rails which is what I want to show. Here’s a brief example.</p>

<p>Let’s imagine we have an <code class="language-plaintext highlighter-rouge">ActiveRecord</code> model like this…</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Airline</span> <span class="o">&lt;</span> <span class="no">ApplicationRecord</span>
    <span class="n">validates</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">presence: </span><span class="kp">true</span>
    <span class="n">validates</span> <span class="ss">:image_url</span><span class="p">,</span> <span class="ss">presence: </span><span class="kp">true</span>

    <span class="n">has_many</span> <span class="ss">:reviews</span>
<span class="k">end</span>
</code></pre></div></div>

<p>You might want to validate that the <code class="language-plaintext highlighter-rouge">name</code> and <code class="language-plaintext highlighter-rouge">image_url</code> are present and it’s a very simple assertion, you might create an <code class="language-plaintext highlighter-rouge">airline</code> with <code class="language-plaintext highlighter-rouge">name</code> and <code class="language-plaintext highlighter-rouge">image_url</code> and if you’re going to test the <code class="language-plaintext highlighter-rouge">name</code> validation you set it to <code class="language-plaintext highlighter-rouge">nil</code> assert that the model is not valid and might also check the errors collection and repeat for the <code class="language-plaintext highlighter-rouge">image_url</code>, simple, right?</p>

<p>Now what about the reviews association? we have several options, one is to check if the <code class="language-plaintext highlighter-rouge">airline</code> model includes the <code class="language-plaintext highlighter-rouge">reviews</code> method via <code class="language-plaintext highlighter-rouge">respond_to?</code> but that’s not accurate because we could have a <code class="language-plaintext highlighter-rouge">def reviews; nil end</code> method defined which will give a false positive, same if we assert that <code class="language-plaintext highlighter-rouge">reviews</code> returns a collection or a number of items if we have a method like this <code class="language-plaintext highlighter-rouge">def reviews; [1,2,3] end</code> it’s still a false positive.</p>

<p>A good thing that I liked about minitest was that there is no out of the box way for you to check for <code class="language-plaintext highlighter-rouge">ActiveRecord</code> associations like what you can do with RSpec/Shoulda, you need to dig a bit into how ActiveRecord handles and reports associations which is good because you get to know <code class="language-plaintext highlighter-rouge">ActiveRecord</code> a bit better.</p>

<p>Now <code class="language-plaintext highlighter-rouge">ActiveRecord</code> has a class method <code class="language-plaintext highlighter-rouge">reflections</code> that you can use in your models which returns associations and aggregations of Active Record models and classes, we can take advantage of that to make sure that we have an actual association instead of a method getting rid of a false positive.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2.7.1 :001 &gt; Airline.reflections
 =&gt; {"reviews"=&gt;#&lt;ActiveRecord::Reflection::HasManyReflection:0x00007ffc1a28d6d8 @name=:reviews, @scope=nil, @options={}, @active_record=Airline (call 'Airline.connection' to establish a connection), @klass=nil, @plural_name="reviews", @type=nil, @foreign_type=nil, @constructable=true, @association_scope_cache=#&lt;Concurrent::Map:0x00007ffc1a28c3f0 entries=0 default_proc=nil&gt;&gt;} 
</code></pre></div></div>

<p>With this knowledge we can create a custom assertion or a helper method inside our Rails <code class="language-plaintext highlighter-rouge">test_helper.rb</code></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Add more helper methods to be used by all tests here...</span>
<span class="k">def</span> <span class="nf">assert_association</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">association</span><span class="p">,</span> <span class="n">association_type</span><span class="p">)</span>
    <span class="n">assert_includes</span> <span class="n">model</span><span class="p">.</span><span class="nf">reflections</span><span class="p">,</span> <span class="n">association</span><span class="p">.</span><span class="nf">to_s</span>

    <span class="n">assert_equal</span> <span class="n">association_type</span><span class="p">,</span> <span class="n">model</span><span class="p">.</span><span class="nf">reflections</span><span class="p">[</span><span class="n">association</span><span class="p">.</span><span class="nf">to_s</span><span class="p">].</span><span class="nf">macro</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Now in <code class="language-plaintext highlighter-rouge">airline_test.rb</code> we can have this test</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">test</span> <span class="s1">'has_many reviews'</span> <span class="k">do</span>
    <span class="n">assert_association</span> <span class="no">Airline</span><span class="p">,</span> <span class="ss">:reviews</span><span class="p">,</span> <span class="ss">:has_many</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Or we can make it a bit more readable by adding two more helper methods inside <code class="language-plaintext highlighter-rouge">test_helper.rb</code></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">assert_has_many</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">association</span><span class="p">)</span>
    <span class="n">assert_association</span> <span class="n">model</span><span class="p">,</span> <span class="n">association</span><span class="p">,</span> <span class="ss">:has_many</span>
<span class="k">end</span>

<span class="k">def</span> <span class="nf">assert_belongs_to</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">association</span><span class="p">)</span>
    <span class="n">assert_association</span> <span class="n">model</span><span class="p">,</span> <span class="n">association</span><span class="p">,</span> <span class="ss">:belongs_to</span>
<span class="k">end</span>
</code></pre></div></div>

<p>So we could have…</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">test</span> <span class="s1">'has_many reviews'</span> <span class="k">do</span>
    <span class="n">assert_has_many</span> <span class="no">Airline</span><span class="p">,</span> <span class="ss">:reviews</span>
<span class="k">end</span>
</code></pre></div></div>

<p>and in <code class="language-plaintext highlighter-rouge">review_test.rb</code></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">test</span> <span class="s1">'belongs_to airline'</span> <span class="k">do</span>
    <span class="n">assert_belongs_to</span> <span class="no">Review</span><span class="p">,</span> <span class="ss">:airline</span>
<span class="k">end</span>
</code></pre></div></div>

<p>See? minispec can be very easy to write and to extend to meet your needs.</p>

<p>If you have any comments or questions feel free to reach out on twitter at <a href="https://twitter.com/fcastellanos">@fcastellanos</a>.</p>]]></content><author><name>Fernando Castellanos</name></author><category term="ruby" /><category term="rails" /><category term="testing" /><category term="minitest" /><category term="tdd" /><summary type="html"><![CDATA[Since I discovered the world of testing and TDD I’ve loved the philosophy behind it and the safety net that it brings. My first interaction with testing was with Ruby on Rails specifically with RSpec, but I’ll admit it, understanding and getting used to testing is not easy but RSpec did a very good job at making it easier and in combination with shoulda matchers makes tests wonderfully easy to read. On the frontend we have Cucumber which is like reading a story but can can take a lot of time and effort to build and maintain, which is one of the reasons why the Steak testing framework was built because it was just ruby, and with this idea I am writing this blog post to talk about why I’m starting to love minitest.]]></summary></entry><entry><title type="html">Software Design Patterns (Builder)</title><link href="https://fcastellanos.io/2020/08/11/software-design-patterns-builder/" rel="alternate" type="text/html" title="Software Design Patterns (Builder)" /><published>2020-08-11T10:30:04-07:00</published><updated>2020-08-11T10:30:04-07:00</updated><id>https://fcastellanos.io/2020/08/11/software-design-patterns-builder</id><content type="html" xml:base="https://fcastellanos.io/2020/08/11/software-design-patterns-builder/"><![CDATA[<p>The seventh and last blog post in the series of Software Design Patterns it’s an interesting one, it’s the Builder Pattern. The builder patter is a unique pattern that allows us to create complex objects out of several simple and independent objects. A key advantage of this pattern is that it creates a clear separation of concerns and a better control over the object that we’re creating.</p>

<p>Here’s an example built in Python:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Director</span><span class="p">:</span>
    <span class="n">__builder</span> <span class="o">=</span> <span class="bp">None</span>

    <span class="k">def</span> <span class="nf">setBuilder</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">builder</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">__builder</span> <span class="o">=</span> <span class="n">builder</span>
    
    <span class="k">def</span> <span class="nf">getCar</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">car</span> <span class="o">=</span> <span class="nc">Car</span><span class="p">()</span>

        <span class="c1"># First goes the body
</span>        <span class="n">body</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">__builder</span><span class="p">.</span><span class="nf">getBody</span><span class="p">()</span>
        <span class="n">car</span><span class="p">.</span><span class="nf">setBody</span><span class="p">(</span><span class="n">body</span><span class="p">)</span>

        <span class="c1"># Then engine
</span>        <span class="n">engine</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">__builder</span><span class="p">.</span><span class="nf">getEngine</span><span class="p">()</span>
        <span class="n">car</span><span class="p">.</span><span class="nf">setEngine</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span>

        <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">4</span><span class="p">:</span>
            <span class="n">wheel</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">__builder</span><span class="p">.</span><span class="nf">getWheel</span><span class="p">()</span>
            <span class="n">car</span><span class="p">.</span><span class="nf">attachWheel</span><span class="p">(</span><span class="n">wheel</span><span class="p">)</span>
            <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
        
        <span class="k">return</span> <span class="n">car</span>

<span class="c1"># The whole product 
</span><span class="k">class</span> <span class="nc">Car</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">__wheels</span> <span class="o">=</span> <span class="nf">list</span><span class="p">()</span>
        <span class="n">self</span><span class="p">.</span><span class="n">__engine</span> <span class="o">=</span> <span class="bp">None</span>
        <span class="n">self</span><span class="p">.</span><span class="n">__body</span> <span class="o">=</span> <span class="bp">None</span>
    
    <span class="k">def</span> <span class="nf">setBody</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">body</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">__body</span> <span class="o">=</span> <span class="n">body</span>
    
    <span class="k">def</span> <span class="nf">attachWheel</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">wheel</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">__wheels</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">wheel</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">setEngine</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">engine</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">__engine</span> <span class="o">=</span> <span class="n">engine</span>
    
    <span class="k">def</span> <span class="nf">specification</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">body: %s</span><span class="sh">"</span> <span class="o">%</span> <span class="n">self</span><span class="p">.</span><span class="n">__body</span><span class="p">.</span><span class="n">shape</span><span class="p">)</span>
        <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">engine horsepower: %d</span><span class="sh">"</span> <span class="o">%</span> <span class="n">self</span><span class="p">.</span><span class="n">__engine</span><span class="p">.</span><span class="n">horsepower</span><span class="p">)</span>
        <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">tire size: %d</span><span class="se">\'</span><span class="sh">"</span> <span class="o">%</span> <span class="n">self</span><span class="p">.</span><span class="n">__wheels</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Builder</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">getWheel</span><span class="p">(</span><span class="n">self</span><span class="p">):</span> <span class="k">pass</span>
    <span class="k">def</span> <span class="nf">getEngine</span><span class="p">(</span><span class="n">self</span><span class="p">):</span> <span class="k">pass</span>
    <span class="k">def</span> <span class="nf">getBody</span><span class="p">(</span><span class="n">self</span><span class="p">):</span> <span class="k">pass</span>

<span class="k">class</span> <span class="nc">JeepBuilder</span><span class="p">(</span><span class="n">Builder</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">getWheel</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">wheel</span> <span class="o">=</span> <span class="nc">Wheel</span><span class="p">()</span>
        <span class="n">wheel</span><span class="p">.</span><span class="n">size</span> <span class="o">=</span> <span class="mi">22</span>
        <span class="k">return</span> <span class="n">wheel</span>
    
    <span class="k">def</span> <span class="nf">getEngine</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">engine</span> <span class="o">=</span> <span class="nc">Engine</span><span class="p">()</span>
        <span class="n">engine</span><span class="p">.</span><span class="n">horsepower</span> <span class="o">=</span> <span class="mi">400</span>
        <span class="k">return</span> <span class="n">engine</span>
    
    <span class="k">def</span> <span class="nf">getBody</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">body</span> <span class="o">=</span> <span class="nc">Body</span><span class="p">()</span>
        <span class="n">body</span><span class="p">.</span><span class="n">shape</span> <span class="o">=</span> <span class="sh">"</span><span class="s">SUV</span><span class="sh">"</span>
        <span class="k">return</span> <span class="n">body</span>

<span class="c1"># Car parts
</span><span class="k">class</span> <span class="nc">Wheel</span><span class="p">:</span>
    <span class="n">size</span> <span class="o">=</span> <span class="bp">None</span>

<span class="k">class</span> <span class="nc">Engine</span><span class="p">:</span>
    <span class="n">horsepower</span> <span class="o">=</span> <span class="bp">None</span>

<span class="k">class</span> <span class="nc">Body</span><span class="p">:</span>
    <span class="n">shape</span> <span class="o">=</span> <span class="bp">None</span>
</code></pre></div></div>

<p>There’s a lot of thing happening here so let’s break it apart. First we see the <code class="language-plaintext highlighter-rouge">Director</code> class which is sort of the director of an orchestra orchestrating the building of a car by setting the different properties of the car like the body, the engine and the wheels. Then we have the <code class="language-plaintext highlighter-rouge">Car</code> class which is basically a shell that receives the different parts of the car with the help of the <code class="language-plaintext highlighter-rouge">Director</code>. Down the code we see the <code class="language-plaintext highlighter-rouge">Builder</code> class which acts more like an interface defining the basic methods for building a car. The <code class="language-plaintext highlighter-rouge">JeepBuilder</code> class inherits from the <code class="language-plaintext highlighter-rouge">Builder</code> class and define the specifics for building a Jeep car by defining the size of the wheels, the horsepower and the shape of a Jeep car, we can create multiple builder classes for different brands of cars. Lastly we have the “placeholder” classes <code class="language-plaintext highlighter-rouge">Wheel</code>, <code class="language-plaintext highlighter-rouge">Engine</code> and <code class="language-plaintext highlighter-rouge">Body</code> we can use for every type of car.</p>

<p>Here’s how we to tie everything together:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">jeepBuilder</span> <span class="o">=</span> <span class="nc">JeepBuilder</span><span class="p">()</span> <span class="c1"># initializing the class
</span><span class="n">director</span>    <span class="o">=</span> <span class="nc">Director</span><span class="p">()</span>

<span class="c1"># Build Jeep
</span><span class="n">director</span><span class="p">.</span><span class="nf">setBuilder</span><span class="p">(</span><span class="n">jeepBuilder</span><span class="p">)</span>
<span class="n">jeep</span> <span class="o">=</span> <span class="n">director</span><span class="p">.</span><span class="nf">getCar</span><span class="p">()</span>
<span class="n">jeep</span><span class="p">.</span><span class="nf">specification</span><span class="p">()</span>
</code></pre></div></div>

<p>Now on this part we instantiate a <code class="language-plaintext highlighter-rouge">JeepBuilder</code> instance and a <code class="language-plaintext highlighter-rouge">Director</code> instance separately and then we set the jeep builder to the director because builder is the one that provides the car parts to the director so it can “attach” them to the <code class="language-plaintext highlighter-rouge">car</code> object when calling the <code class="language-plaintext highlighter-rouge">getCar()</code> method. Lastly we call the <code class="language-plaintext highlighter-rouge">specification()</code> method on the <code class="language-plaintext highlighter-rouge">jeep</code> instance which displays the car properties showing that everything’s working properly.</p>

<p>This might take a bit of time to get used to but it’s a very powerful pattern that allows you to have everything separated and just build complex objects like if they were LEGO blocks.</p>

<p>As always if you have any comments or questions feel free to reach out on twitter at <a href="https://twitter.com/fcastellanos">@fcastellanos</a>.</p>]]></content><author><name>Fernando Castellanos</name></author><category term="design patterns" /><category term="software patterns" /><category term="best practices" /><category term="builder" /><category term="python" /><category term="software development" /><summary type="html"><![CDATA[The seventh and last blog post in the series of Software Design Patterns it’s an interesting one, it’s the Builder Pattern. The builder patter is a unique pattern that allows us to create complex objects out of several simple and independent objects. A key advantage of this pattern is that it creates a clear separation of concerns and a better control over the object that we’re creating.]]></summary></entry><entry><title type="html">Software Design Patterns (Strategy)</title><link href="https://fcastellanos.io/2020/08/03/software-design-patterns-strategy/" rel="alternate" type="text/html" title="Software Design Patterns (Strategy)" /><published>2020-08-03T11:23:23-07:00</published><updated>2020-08-03T11:23:23-07:00</updated><id>https://fcastellanos.io/2020/08/03/software-design-patterns-strategy</id><content type="html" xml:base="https://fcastellanos.io/2020/08/03/software-design-patterns-strategy/"><![CDATA[<p>In the sixth installment of the Software Design Patterns blog series I’ll talk about the Strategy Pattern. This pattern is interesting because it allows the consumer of this code to choose what “strategy” it wants to use to do the work that needs to be done. You could have a list of different algorithms that are interchangeable and depending on the need we can choose one or the other. You can use this pattern in conjunction with the Adapter Pattern.</p>

<p>Let’s see an example.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">types</span>

<span class="k">class</span> <span class="nc">StrategyExample</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">func</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="sh">'</span><span class="s">Strategy Example 0</span><span class="sh">'</span>

        <span class="k">if</span> <span class="n">func</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
            <span class="n">self</span><span class="p">.</span><span class="n">execute</span> <span class="o">=</span> <span class="n">types</span><span class="p">.</span><span class="nc">MethodType</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="n">self</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="nf">print</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">name</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">execute_replacement1</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">name</span> <span class="o">+</span> <span class="sh">'</span><span class="s"> from execute 1</span><span class="sh">'</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">execute_replacement2</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">name</span> <span class="o">+</span> <span class="sh">'</span><span class="s"> from execute 2</span><span class="sh">'</span><span class="p">)</span>
</code></pre></div></div>

<p>If we see the <code class="language-plaintext highlighter-rouge">StrategyExample</code> class it has an <code class="language-plaintext highlighter-rouge">execute</code> function that just prints out the <code class="language-plaintext highlighter-rouge">name</code> property, but in the initializer it can receive a <code class="language-plaintext highlighter-rouge">func</code> parameter that would be a function that replaces the <code class="language-plaintext highlighter-rouge">execute</code> function if <code class="language-plaintext highlighter-rouge">func</code> is present.</p>

<p>Down below we also see two functions <code class="language-plaintext highlighter-rouge">execute_replacement1</code> and <code class="language-plaintext highlighter-rouge">execute_replacement2</code> that just prints out a property <code class="language-plaintext highlighter-rouge">name</code> plus something else, the purpose of these functions is to act as replacements for the <code class="language-plaintext highlighter-rouge">execute</code> functions for the <code class="language-plaintext highlighter-rouge">StrategyExample</code> class</p>

<p>Now let’s see how we can implement it</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">strat0</span> <span class="o">=</span> <span class="nc">StrategyExample</span><span class="p">()</span>

<span class="n">strat1</span> <span class="o">=</span> <span class="nc">StrategyExample</span><span class="p">(</span><span class="n">execute_replacement1</span><span class="p">)</span>
<span class="n">strat1</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="sh">'</span><span class="s">Strategy Example 1</span><span class="sh">'</span>

<span class="n">strat2</span> <span class="o">=</span> <span class="nc">StrategyExample</span><span class="p">(</span><span class="n">execute_replacement2</span><span class="p">)</span>
<span class="n">strat2</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="sh">'</span><span class="s">Strategy Example 2</span><span class="sh">'</span>

<span class="n">strat0</span><span class="p">.</span><span class="nf">execute</span><span class="p">()</span>
<span class="n">strat1</span><span class="p">.</span><span class="nf">execute</span><span class="p">()</span>
<span class="n">strat2</span><span class="p">.</span><span class="nf">execute</span><span class="p">()</span>
</code></pre></div></div>

<p>We create 3 instances of the <code class="language-plaintext highlighter-rouge">StrategyExample</code> class, one with no replacement and the other two with replacements for the <code class="language-plaintext highlighter-rouge">execute</code> function with <code class="language-plaintext highlighter-rouge">execute_replacement1</code> and <code class="language-plaintext highlighter-rouge">execute_replacement2</code>, after the three initializations we call <code class="language-plaintext highlighter-rouge">execute</code> on the three instances of the same class but see three different results, in this case the three implementations use the <code class="language-plaintext highlighter-rouge">name</code> property but in three different ways, this is the flexibility of the Strategy Pattern.</p>

<p>If you have any comments or questions feel free to reach out on twitter at <a href="https://twitter.com/fcastellanos">@fcastellanos</a>.</p>]]></content><author><name>Fernando Castellanos</name></author><category term="design patterns" /><category term="software patterns" /><category term="best practices" /><category term="strategy" /><category term="python" /><category term="software development" /><summary type="html"><![CDATA[In the sixth installment of the Software Design Patterns blog series I’ll talk about the Strategy Pattern. This pattern is interesting because it allows the consumer of this code to choose what “strategy” it wants to use to do the work that needs to be done. You could have a list of different algorithms that are interchangeable and depending on the need we can choose one or the other. You can use this pattern in conjunction with the Adapter Pattern.]]></summary></entry><entry><title type="html">Refactor a Never Ending ‘if’ Statements Into a Rule System</title><link href="https://fcastellanos.io/2020/07/26/refactor-a-never-ending-if-statements-into-a-rule-system/" rel="alternate" type="text/html" title="Refactor a Never Ending ‘if’ Statements Into a Rule System" /><published>2020-07-26T13:31:27-07:00</published><updated>2020-07-26T13:31:27-07:00</updated><id>https://fcastellanos.io/2020/07/26/refactor-a-never-ending-if-statements-into-a-rule-system</id><content type="html" xml:base="https://fcastellanos.io/2020/07/26/refactor-a-never-ending-if-statements-into-a-rule-system/"><![CDATA[<p>This comes from a personal experience while working on a big refactor of an Ad Server, in an ad serving system you have creatives, campaigns, ad units, templates, etc. On the client side, meaning the website that will server the Ad it serves the creative code that will ultimately calls the Ad Server requesting an Ad by sending the Creative ID, along with the client information coming from the HTTP request. What can be really messy and complicated is that whenever you request an Ad to an Ad Server is that the request goes through what some call a Campaign and a Creative auction to determine which Ad to serve, these auctions checks for a matching campaign meaning that you cannot serve any Ad to any request, it needs to match certain campaigns requirements and after matching a campaign it needs to match a creative requirements, the amount of requirements can vary or each of them.</p>

<p>For the Campaign Auction that I was rewriting for the Ad Server there were around 27 rules, there were rules to check if the requested Creative existed, GeoIP related rules, Language rules, among a bunch of other rules, in order to find a marching Campaign for that request, all 27 rules had to apply. To make this a bit more complicated the order of some of those rules did matter and it was not rare if we had to add or remove some of those rules. Now the reason why we had the need to rewrite this part of the Ad Server it was because the way that this was written in the first place, I’ll try to illustrate this without showing the actual code.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">creative_id</span><span class="sh">'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">creatives</span><span class="sh">'</span><span class="p">]:</span>
    <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">country</span><span class="sh">'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">countries</span><span class="sh">'</span><span class="p">]:</span>
        <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">region</span><span class="sh">'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">regions</span><span class="sh">'</span><span class="p">]:</span>
            <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">city</span><span class="sh">'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">cities</span><span class="sh">'</span><span class="p">]:</span>
                <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">language</span><span class="sh">'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">languages</span><span class="sh">'</span><span class="p">]:</span>
                    <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_1</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_1</span><span class="sh">'</span><span class="p">]:</span>
                        <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_2</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_2</span><span class="sh">'</span><span class="p">]:</span>
                            <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_3</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_3</span><span class="sh">'</span><span class="p">]:</span>
                                <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_4</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_4</span><span class="sh">'</span><span class="p">]:</span>
                                    <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_5</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_5</span><span class="sh">'</span><span class="p">]:</span>
                                        <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_6</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_6</span><span class="sh">'</span><span class="p">]:</span>
                                            <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_7</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_7</span><span class="sh">'</span><span class="p">]:</span>
                                                <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_8</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_8</span><span class="sh">'</span><span class="p">]:</span>
                                                    <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_9</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_9</span><span class="sh">'</span><span class="p">]:</span>
                                                        <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_10</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_10</span><span class="sh">'</span><span class="p">]:</span>
                                                            <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_11</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_11</span><span class="sh">'</span><span class="p">]:</span>
                                                                <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_12</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_12</span><span class="sh">'</span><span class="p">]:</span>
                                                                    <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_13</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_13</span><span class="sh">'</span><span class="p">]:</span>
                                                                        <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_14</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_14</span><span class="sh">'</span><span class="p">]:</span>
                                                                            <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_15</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_15</span><span class="sh">'</span><span class="p">]:</span>
                                                                                <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_16</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_16</span><span class="sh">'</span><span class="p">]:</span>
                                                                                    <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_17</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_17</span><span class="sh">'</span><span class="p">]:</span>
                                                                                        <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_18</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_18</span><span class="sh">'</span><span class="p">]:</span>
                                                                                            <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_19</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_19</span><span class="sh">'</span><span class="p">]:</span>
                                                                                                <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_20</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_20</span><span class="sh">'</span><span class="p">]:</span>
                                                                                                    <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_21</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_21</span><span class="sh">'</span><span class="p">]:</span>
                                                                                                        <span class="k">if</span> <span class="n">client</span><span class="p">[</span><span class="sh">'</span><span class="s">param_22</span><span class="sh">'</span><span class="p">]</span> <span class="o">==</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">param_22</span><span class="sh">'</span><span class="p">]:</span>
                                                                                                            <span class="c1"># Finally found a matching campaign
</span></code></pre></div></div>

<p>No joke this was exactly how it was built but in PHP, the cherry on top was that this code had no tests at all, no wonder why programmers hate PHP but don’t blame PHP, it’s the lack of programming principles.</p>

<p>Each rule was not as simple as it’s portrayed here, some had multiple conditions, some of those multiple conditions called other functions, if there was something to rescue from this was that each condition had a comment explaining briefly what it was evaluating.</p>

<p>The first thing that I thought that I should do to refactor this mess was to have some test coverage as a safety net to make sure I was going in the right path, but by looking at the amount of nested conditions it was going to be a nightmare to create the different test scenarios to try and reach the maximum test coverage, next thing that I thought that would help was to give each condition a name and by that I mean to use the “extract method” pattern to extract each condition into its own boolean function, that would give a meaningful name to each condition in order to start giving it some shape and form. But definitely my best move was to ask my coworkers for suggestions, one suggested to build an array of functions and loop through each function and the moment that one function returned false we could break out of the loop because all conditions must meet in order to proceed, that suggestion was clever because it prevented the need to have nested if statements and reduced the code and the complexity by leaps and bounds, my other co-worker suggested to take a peak at an Avdi Grimm post called <a href="https://www.rubytapas.com/2018/07/03/rule-object/">“Your business rules are objects too”</a> which is a great article that helped take my solution an even greater form.</p>

<p>Now, there’s a twist to this story, the logical or conceptual Campaign Auction code was inside a a file that was around 2000 lines of code within a function that was probably 300 lines give or take, first thing was to extract the Campaign Auction code into a <code class="language-plaintext highlighter-rouge">CampaignAuction</code> class that would only do the Campaign Auction and nothing else long live SRP (Single Responsibility Principle). Once I managed to logically constrain the Campaign Auction code, it was time to get working on the refactor, I started by also extracting each condition into its own rule class that followed a simple interface with an <code class="language-plaintext highlighter-rouge">applies</code> boolean function, this means that I ended up with 27 rule classes all following the same interface.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">CreativeExistRule</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">campaign</span><span class="p">,</span> <span class="n">client_data</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">client_data</span> <span class="o">=</span> <span class="n">client_data</span>
    
    <span class="k">def</span> <span class="nf">applies</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">client_data</span><span class="p">[</span><span class="sh">'</span><span class="s">creative_id</span><span class="sh">'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">creatives</span><span class="sh">'</span><span class="p">]</span>

<span class="k">class</span> <span class="nc">CountryRule</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">campaign</span><span class="p">,</span> <span class="n">client_data</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">client_data</span> <span class="o">=</span> <span class="n">client_data</span>
    
    <span class="k">def</span> <span class="nf">applies</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">client_data</span><span class="p">[</span><span class="sh">'</span><span class="s">country</span><span class="sh">'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">countries</span><span class="sh">'</span><span class="p">]</span>

<span class="k">class</span> <span class="nc">RegionRule</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">campaign</span><span class="p">,</span> <span class="n">client_data</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">client_data</span> <span class="o">=</span> <span class="n">client_data</span>
    
    <span class="k">def</span> <span class="nf">applies</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">client_data</span><span class="p">[</span><span class="sh">'</span><span class="s">region</span><span class="sh">'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">regions</span><span class="sh">'</span><span class="p">]</span>

<span class="k">class</span> <span class="nc">CityRule</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">campaign</span><span class="p">,</span> <span class="n">client_data</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">client_data</span> <span class="o">=</span> <span class="n">client_data</span>
    
    <span class="k">def</span> <span class="nf">applies</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">client_data</span><span class="p">[</span><span class="sh">'</span><span class="s">city</span><span class="sh">'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">campaign</span><span class="p">[</span><span class="sh">'</span><span class="s">cities</span><span class="sh">'</span><span class="p">]</span>
</code></pre></div></div>

<p>This separation of concerns is great because it makes the code really testable by being able to test each rule in isolation.</p>

<p>Let’s see how the Campaign Auction class looks like after separating the logic from the 2000+ lines of code file.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">CampaignAuction</span><span class="p">:</span>    
    <span class="n">rules</span> <span class="o">=</span> <span class="p">[</span>
        <span class="sh">'</span><span class="s">CreativeExistRule</span><span class="sh">'</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">CountryRule</span><span class="sh">'</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">RegionRule</span><span class="sh">'</span><span class="p">,</span>
        <span class="sh">'</span><span class="s">CityRule</span><span class="sh">'</span><span class="p">,</span>
    <span class="p">]</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">campaign</span><span class="p">,</span> <span class="n">client_data</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">campaign</span> <span class="o">=</span> <span class="n">campaign</span>
        <span class="n">self</span><span class="p">.</span><span class="n">client_data</span> <span class="o">=</span> <span class="n">client_data</span>

    <span class="k">def</span> <span class="nf">perform</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">meets_all</span> <span class="o">=</span> <span class="bp">True</span>
        <span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="n">rules</span><span class="p">:</span>
            <span class="n">rule_constant</span> <span class="o">=</span> <span class="nf">globals</span><span class="p">()[</span><span class="n">rule</span><span class="p">]</span>
            <span class="n">rule_instance</span> <span class="o">=</span> <span class="nf">rule_constant</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">campaign</span><span class="p">,</span> <span class="n">self</span><span class="p">.</span><span class="n">client_data</span><span class="p">)</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">rule_instance</span><span class="p">.</span><span class="nf">applies</span><span class="p">():</span>
                <span class="n">meets_all</span> <span class="o">=</span> <span class="bp">False</span>
                <span class="k">break</span>
        <span class="k">return</span> <span class="n">meets_all</span>
</code></pre></div></div>

<p>It’s really easy to see how this is much better than having all those nested if conditions that are virtually impossible to test under the current conditions. Now allow me to explain how this rule system works.</p>

<p>First thing to notice is the <code class="language-plaintext highlighter-rouge">rules</code> property in the <code class="language-plaintext highlighter-rouge">CampaignAuction</code> class, this is a list of the string representation of the class names of each rule class, we should be able to easily add and remove rules. Next is the <code class="language-plaintext highlighter-rouge">__init__</code> function that takes the <code class="language-plaintext highlighter-rouge">campaign</code> data that we’re currently evaluating, we’ll be instantiating a new auction for each campaign that we want to check against, we’re also passing the <code class="language-plaintext highlighter-rouge">client_data</code> that will hold data coming from the request. Lastly we see the <code class="language-plaintext highlighter-rouge">perform</code> function that performs the actual auction. The “magic” happens by looping through each rule and finding the rule constant/class in the Python globals <code class="language-plaintext highlighter-rouge">globals()[rule]</code> and then we create an instance of that rule with <code class="language-plaintext highlighter-rouge">rule_constant(self.campaign, self.client_data)</code>, after we have the instance we call the <code class="language-plaintext highlighter-rouge">applies()</code> function if any of the rules return false we break out of the loop and return <code class="language-plaintext highlighter-rouge">False</code> to the <code class="language-plaintext highlighter-rouge">perform</code> function, if none of the rules return false then we’ll be returning <code class="language-plaintext highlighter-rouge">True</code> to the function. We are able to do this regardless of the rule that’s being evaluated because <strong>all</strong> rules follow the same interface.</p>

<p>Final thoughts for this will be that we should always be testing our code, it works as a design tool, as documentation and also to give us peace of mind before we deploy to production. Another thing to keep in mind is to never be afraid to ask your coworkers for opinions, always keep an open channel for conversation around the ideas on how to solve a problem. Lastly inform yourself about software patterns and principles that will guide you to be a better developer, read blogs, books, talk to other developers, attend meetings, join developer groups, give talks and in general be involved in the overall developer community, you’ll always learn something new.</p>

<p>If you have any comments or questions feel free to reach out on twitter at <a href="https://twitter.com/fcastellanos">@fcastellanos</a>.</p>]]></content><author><name>Fernando Castellanos</name></author><category term="php" /><category term="patterns" /><category term="best-practices" /><summary type="html"><![CDATA[This comes from a personal experience while working on a big refactor of an Ad Server, in an ad serving system you have creatives, campaigns, ad units, templates, etc. On the client side, meaning the website that will server the Ad it serves the creative code that will ultimately calls the Ad Server requesting an Ad by sending the Creative ID, along with the client information coming from the HTTP request. What can be really messy and complicated is that whenever you request an Ad to an Ad Server is that the request goes through what some call a Campaign and a Creative auction to determine which Ad to serve, these auctions checks for a matching campaign meaning that you cannot serve any Ad to any request, it needs to match certain campaigns requirements and after matching a campaign it needs to match a creative requirements, the amount of requirements can vary or each of them.]]></summary></entry><entry><title type="html">Software Design Patterns (Adapter)</title><link href="https://fcastellanos.io/2020/07/25/software-design-patterns-adapter/" rel="alternate" type="text/html" title="Software Design Patterns (Adapter)" /><published>2020-07-25T18:05:12-07:00</published><updated>2020-07-25T18:05:12-07:00</updated><id>https://fcastellanos.io/2020/07/25/software-design-patterns-adapter</id><content type="html" xml:base="https://fcastellanos.io/2020/07/25/software-design-patterns-adapter/"><![CDATA[<p>In this fifth part of the Software Design Patterns blog series I’ll talk about a pattern that probably most of us have heard of or even used before but that we haven’t had the opportunity to build, I’m talking about the Adapter Pattern.</p>

<p>The Adapter pattern acts as a bridge between two incompatible classes by “adapting” the functionality of one class into the other via an interface. One of the most popular examples of the Adapter Pattern is how different programming languages uses Adapter classes to access a database, it’s very common to se <code class="language-plaintext highlighter-rouge">MySqlDataAdapter</code>, <code class="language-plaintext highlighter-rouge">PgSqlDataAdapter</code>, etc, what these adapters are doing is creating a bridge or “adapting” into the specificities of each database engine so you don’t have to worry about those minor details or worse having to create your own adapters.</p>

<p>Now let’s look at an example with an electrical socket analogy.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">EuropeanSocketInterface</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">voltage</span><span class="p">(</span><span class="n">self</span><span class="p">):</span> <span class="k">pass</span>
    <span class="k">def</span> <span class="nf">live</span><span class="p">(</span><span class="n">self</span><span class="p">):</span> <span class="k">pass</span>
    <span class="k">def</span> <span class="nf">neutral</span><span class="p">(</span><span class="n">self</span><span class="p">):</span> <span class="k">pass</span>
    <span class="k">def</span> <span class="nf">earth</span><span class="p">(</span><span class="n">self</span><span class="p">):</span> <span class="k">pass</span>

<span class="c1"># Adaptee
</span><span class="k">class</span> <span class="nc">Socket</span><span class="p">(</span><span class="n">EuropeanSocketInterface</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">voltage</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="mi">230</span>
    
    <span class="k">def</span> <span class="nf">live</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="mi">1</span>
    
    <span class="k">def</span> <span class="nf">neutral</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span>
    
    <span class="k">def</span> <span class="nf">earth</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="mi">0</span>
    
<span class="c1"># Target interface
</span><span class="k">class</span> <span class="nc">USASocketInterface</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">voltage</span><span class="p">(</span><span class="n">self</span><span class="p">):</span> <span class="k">pass</span>
    <span class="k">def</span> <span class="nf">live</span><span class="p">(</span><span class="n">self</span><span class="p">):</span> <span class="k">pass</span>
    <span class="k">def</span> <span class="nf">neutral</span><span class="p">(</span><span class="n">self</span><span class="p">):</span> <span class="k">pass</span>

<span class="c1"># The Adapter
</span><span class="k">class</span> <span class="nc">Adapter</span><span class="p">(</span><span class="n">USASocketInterface</span><span class="p">):</span>
    <span class="n">__socket</span> <span class="o">=</span> <span class="bp">None</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">socket</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">__socket</span> <span class="o">=</span> <span class="n">socket</span>
    
    <span class="k">def</span> <span class="nf">voltage</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="mi">110</span>
    
    <span class="k">def</span> <span class="nf">live</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">__socket</span><span class="p">.</span><span class="nf">live</span><span class="p">()</span>
    
    <span class="k">def</span> <span class="nf">neutral</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">__socket</span><span class="p">.</span><span class="nf">neutral</span><span class="p">()</span>

<span class="c1"># Client
</span><span class="k">class</span> <span class="nc">ElectricKettle</span><span class="p">:</span>
    <span class="n">__power</span> <span class="o">=</span> <span class="bp">None</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">power</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">__power</span> <span class="o">=</span> <span class="n">power</span>
    
    <span class="k">def</span> <span class="nf">boil</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">self</span><span class="p">.</span><span class="n">__power</span><span class="p">.</span><span class="nf">voltage</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mi">110</span><span class="p">:</span>
            <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Halt and catch fire!</span><span class="sh">"</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">self</span><span class="p">.</span><span class="n">__power</span><span class="p">.</span><span class="nf">live</span><span class="p">()</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">self</span><span class="p">.</span><span class="n">__power</span><span class="p">.</span><span class="nf">neutral</span><span class="p">()</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
                <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Coffee time!</span><span class="sh">"</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span> 
                <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">No power.</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<p>In this example we have a socket which is European type (<code class="language-plaintext highlighter-rouge">EuropeanSocketInterface</code>) and we have a Kettle which have an electrical plug of the type we use in the US (<code class="language-plaintext highlighter-rouge">USASocketInterface</code>), now in order for us to be able to plug the Kettle in the European style socket we need to use an adapter (<code class="language-plaintext highlighter-rouge">Adapter</code>) that will use the <code class="language-plaintext highlighter-rouge">USASocketInterface</code>, if you check both socket interfaces the European and the USA we see that both have similar interface (<code class="language-plaintext highlighter-rouge">voltage</code>, <code class="language-plaintext highlighter-rouge">live</code>, <code class="language-plaintext highlighter-rouge">neutral</code>).</p>

<p>Now let’s see the example.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">socket</span> <span class="o">=</span> <span class="nc">Socket</span><span class="p">()</span>
<span class="n">adapter</span> <span class="o">=</span> <span class="nc">Adapter</span><span class="p">(</span><span class="n">socket</span><span class="p">)</span>
<span class="n">kettle</span> <span class="o">=</span> <span class="nc">ElectricKettle</span><span class="p">(</span><span class="n">adapter</span><span class="p">)</span>

<span class="n">kettle</span><span class="p">.</span><span class="nf">boil</span><span class="p">()</span>
</code></pre></div></div>

<p>The output being</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Coffee time!
</code></pre></div></div>

<p>Here you can see the <code class="language-plaintext highlighter-rouge">ElectricKettle</code> class using the adapter (<code class="language-plaintext highlighter-rouge">Adapter</code>) to adapt to the European style socket. And if you check the <code class="language-plaintext highlighter-rouge">Adapter</code> we can see that we’re really only overriding the value of <code class="language-plaintext highlighter-rouge">voltage</code> with <code class="language-plaintext highlighter-rouge">110</code> which is what the <code class="language-plaintext highlighter-rouge">ElectricKettle</code> use, in the case that it’s higher than <code class="language-plaintext highlighter-rouge">110</code> it will <code class="language-plaintext highlighter-rouge">"Halt and catch fire!"</code>, on the other hand if everything else is correct it’s going to be <code class="language-plaintext highlighter-rouge">"Coffee time!"</code> or <code class="language-plaintext highlighter-rouge">"No power."</code>.</p>

<p>And this is it for the Adapter pattern hope it’s clear enough, if you have any comments or questions feel free to reach out on twitter at <a href="https://twitter.com/fcastellanos">@fcastellanos</a>.</p>]]></content><author><name>Fernando Castellanos</name></author><category term="design patterns" /><category term="software patterns" /><category term="best practices" /><category term="adapter" /><summary type="html"><![CDATA[In this fifth part of the Software Design Patterns blog series I’ll talk about a pattern that probably most of us have heard of or even used before but that we haven’t had the opportunity to build, I’m talking about the Adapter Pattern.]]></summary></entry><entry><title type="html">Software Design Patterns (State)</title><link href="https://fcastellanos.io/2020/07/25/software-design-patterns-state/" rel="alternate" type="text/html" title="Software Design Patterns (State)" /><published>2020-07-25T14:30:16-07:00</published><updated>2020-07-25T14:30:16-07:00</updated><id>https://fcastellanos.io/2020/07/25/software-design-patterns-state</id><content type="html" xml:base="https://fcastellanos.io/2020/07/25/software-design-patterns-state/"><![CDATA[<p>This is the fourth part of the Software Design Patterns blog post series, in this post I’m going to talk about the State Pattern or the State Machine Pattern, which is a pattern that defines a way to transition between the state of a process and allows you to define the rules of the transition.</p>

<p>I’ll explain it with an analogy of the state of a computer.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">ComputerState</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="n">name</span>    <span class="o">=</span> <span class="sh">"</span><span class="s">state</span><span class="sh">"</span>
    <span class="n">allowed</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">def</span> <span class="nf">switch</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">state</span><span class="p">):</span>
        <span class="c1"># Switch to new state
</span>        <span class="k">if</span> <span class="n">state</span><span class="p">.</span><span class="n">name</span> <span class="ow">in</span> <span class="n">self</span><span class="p">.</span><span class="n">allowed</span><span class="p">:</span>
            <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Current:</span><span class="sh">"</span><span class="p">,</span> <span class="n">self</span><span class="p">,</span> <span class="sh">"</span><span class="s"> =&gt; switched to new state</span><span class="sh">"</span><span class="p">,</span> <span class="n">state</span><span class="p">.</span><span class="n">name</span><span class="p">)</span>
            <span class="n">self</span><span class="p">.</span><span class="n">__class__</span> <span class="o">=</span> <span class="n">state</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Current:</span><span class="sh">"</span><span class="p">,</span> <span class="n">self</span><span class="p">,</span> <span class="sh">"</span><span class="s"> =&gt; switching to</span><span class="sh">"</span><span class="p">,</span> <span class="n">state</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="sh">"</span><span class="s">not possible.</span><span class="sh">"</span><span class="p">)</span>
    
    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">name</span>

<span class="k">class</span> <span class="nc">Off</span><span class="p">(</span><span class="n">ComputerState</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="sh">"</span><span class="s">off</span><span class="sh">"</span>
    <span class="n">allowed</span> <span class="o">=</span> <span class="p">[</span><span class="sh">'</span><span class="s">on</span><span class="sh">'</span><span class="p">]</span>

<span class="k">class</span> <span class="nc">On</span><span class="p">(</span><span class="n">ComputerState</span><span class="p">):</span>
    <span class="c1"># State of being powered on and working
</span>    <span class="n">name</span> <span class="o">=</span> <span class="sh">"</span><span class="s">on</span><span class="sh">"</span>
    <span class="n">allowed</span> <span class="o">=</span> <span class="p">[</span><span class="sh">'</span><span class="s">off</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">suspend</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">hibernate</span><span class="sh">'</span><span class="p">]</span>

<span class="k">class</span> <span class="nc">Suspend</span><span class="p">(</span><span class="n">ComputerState</span><span class="p">):</span>
    <span class="c1"># State of being in suspended mode after switched on
</span>    <span class="n">name</span> <span class="o">=</span> <span class="sh">"</span><span class="s">suspend</span><span class="sh">"</span>
    <span class="n">allowed</span> <span class="o">=</span> <span class="p">[</span><span class="sh">'</span><span class="s">on</span><span class="sh">'</span><span class="p">]</span>

<span class="k">class</span> <span class="nc">Hibernate</span><span class="p">(</span><span class="n">ComputerState</span><span class="p">):</span>
    <span class="c1"># State of being in hibernation after powered on
</span>    <span class="n">name</span> <span class="o">=</span> <span class="sh">"</span><span class="s">hibernate</span><span class="sh">"</span>
    <span class="n">allowed</span> <span class="o">=</span> <span class="p">[</span><span class="sh">'</span><span class="s">on</span><span class="sh">'</span><span class="p">]</span>

<span class="k">class</span> <span class="nc">Computer</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="c1">#  A class representing a computer
</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="sh">'</span><span class="s">HP</span><span class="sh">'</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">model</span> <span class="o">=</span> <span class="n">model</span>
        <span class="c1"># State on the computer - default is off.
</span>        <span class="n">self</span><span class="p">.</span><span class="n">state</span> <span class="o">=</span> <span class="nc">Off</span><span class="p">()</span>
    
    <span class="k">def</span> <span class="nf">change</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">state</span><span class="p">):</span>
        <span class="c1"># Change state
</span>        <span class="n">self</span><span class="p">.</span><span class="n">state</span><span class="p">.</span><span class="nf">switch</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>
</code></pre></div></div>

<p>There’s a lot going on here so let me break it down. First we see the <code class="language-plaintext highlighter-rouge">ComputerState</code> class which is the one that will orchestrate the switching of the state by checking if we’re allowed to change the state of the process or not, in this case it’s doing the checking/switching via the <code class="language-plaintext highlighter-rouge">switch</code> function.</p>

<p>Then we also have the <code class="language-plaintext highlighter-rouge">Off</code>, <code class="language-plaintext highlighter-rouge">On</code>, <code class="language-plaintext highlighter-rouge">Suspend</code> and <code class="language-plaintext highlighter-rouge">Hibernate</code> classes which inherits from the <code class="language-plaintext highlighter-rouge">ComputerState</code> class, each of those state classes have their own <code class="language-plaintext highlighter-rouge">name</code> and <code class="language-plaintext highlighter-rouge">allowed</code> properties, the <code class="language-plaintext highlighter-rouge">name</code> property is self explanatory but the <code class="language-plaintext highlighter-rouge">allowed</code> property is a list of allowed states to switch from the current state of the state machine.</p>

<p>Finally we have the <code class="language-plaintext highlighter-rouge">Computer</code> class which have two properties, <code class="language-plaintext highlighter-rouge">model</code> that specifies the model of the computer, and <code class="language-plaintext highlighter-rouge">state</code> that indicates the state of the computer via a state machine, at the beginning the computer’s state will be <code class="language-plaintext highlighter-rouge">Off</code>, the <code class="language-plaintext highlighter-rouge">Computer</code> class also defines the <code class="language-plaintext highlighter-rouge">change</code> function which takes the state that we want to switch to. If we look closer to the <code class="language-plaintext highlighter-rouge">change</code> function in the <code class="language-plaintext highlighter-rouge">Computer</code> class it’s calling the <code class="language-plaintext highlighter-rouge">switch</code> function in the current state instance, now going back to the <code class="language-plaintext highlighter-rouge">ComputerState</code> class we can see that the <code class="language-plaintext highlighter-rouge">switch</code> function checks if the state that we want to switch to is in the <code class="language-plaintext highlighter-rouge">allowed</code> list, if it is in the allowed list we switch to that state if it isn’t we print out that switching to that state it’s not possible.</p>

<p>This pattern might take a bit of upfront work to fully define the states and the rules but once you define them it’s going to make your life easier and it will also avoid having a bunch of if statements checking rules and states.</p>

<p>As always if you have any comments or questions feel free to reach out on twitter at <a href="https://twitter.com/fcastellanos">@fcastellanos</a>.</p>]]></content><author><name>Fernando Castellanos</name></author><category term="design patterns" /><category term="software patterns" /><category term="best practices" /><category term="state" /><summary type="html"><![CDATA[This is the fourth part of the Software Design Patterns blog post series, in this post I’m going to talk about the State Pattern or the State Machine Pattern, which is a pattern that defines a way to transition between the state of a process and allows you to define the rules of the transition.]]></summary></entry><entry><title type="html">Software Design Patterns (Observer)</title><link href="https://fcastellanos.io/2020/07/25/software-design-patterns-observer/" rel="alternate" type="text/html" title="Software Design Patterns (Observer)" /><published>2020-07-25T12:15:27-07:00</published><updated>2020-07-25T12:15:27-07:00</updated><id>https://fcastellanos.io/2020/07/25/software-design-patterns-observer</id><content type="html" xml:base="https://fcastellanos.io/2020/07/25/software-design-patterns-observer/"><![CDATA[<p>This the third part of the Software Design Patterns series, in this post I’m going to talk about the Observer Pattern. This pattern is not exactly the same as the Publisher/Subscriber pattern but is very similar in the way that we have a publisher instance that publishes messages and we also have subscribers that are subscribed to the publisher’s messages.</p>

<p>This pattern can be really useful because we could build a workflow where we can have the Publisher publish to the subscribers that an image have been downloaded and then have the subscribers transform that image into multiple formats. This pattern also allows us to extend features via “plug n play” without the other subscribers knowing, we can also remove subscribers without affecting the whole workflow.</p>

<p>Here’s how you’d build the Observer pattern in Python:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Subscriber</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
    
    <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
        <span class="nf">print</span><span class="p">(</span><span class="sh">'</span><span class="s">{} got message </span><span class="sh">"</span><span class="s">{}</span><span class="sh">"'</span><span class="p">.</span><span class="nf">format</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="n">message</span><span class="p">))</span>

<span class="k">class</span> <span class="nc">Publisher</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">subscribers</span> <span class="o">=</span> <span class="nf">set</span><span class="p">()</span>
    
    <span class="k">def</span> <span class="nf">register</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">who</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">subscribers</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="n">who</span><span class="p">)</span>
    
    <span class="k">def</span> <span class="nf">unregister</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">who</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">subscribers</span><span class="p">.</span><span class="nf">discard</span><span class="p">(</span><span class="n">who</span><span class="p">)</span>
    
    <span class="k">def</span> <span class="nf">dispatch</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">subscriber</span> <span class="ow">in</span> <span class="n">self</span><span class="p">.</span><span class="n">subscribers</span><span class="p">:</span>
            <span class="n">subscriber</span><span class="p">.</span><span class="nf">update</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
</code></pre></div></div>

<p>In this example you see the <code class="language-plaintext highlighter-rouge">Subscriber</code> class that have a property <code class="language-plaintext highlighter-rouge">name</code> and an <code class="language-plaintext highlighter-rouge">update</code> function that the subscriber will call whenever it publishes a message. On the other side we have the <code class="language-plaintext highlighter-rouge">Publisher</code> class that have a <code class="language-plaintext highlighter-rouge">subscribers</code> property which is going to hold a list of subscribers that it needs to send messages to, it also have a <code class="language-plaintext highlighter-rouge">register</code> and <code class="language-plaintext highlighter-rouge">unregister</code> functions to add or remove subscribers from the list. Finally the <code class="language-plaintext highlighter-rouge">Publisher</code> class also have a <code class="language-plaintext highlighter-rouge">dispatch</code> function which is the one responsible to receive a message and passing that message to all of its subscribers.</p>

<p>This is how you’d run this</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pub</span> <span class="o">=</span> <span class="nc">Publisher</span><span class="p">()</span>

<span class="n">juan</span> <span class="o">=</span> <span class="nc">Subscriber</span><span class="p">(</span><span class="sh">'</span><span class="s">Juan</span><span class="sh">'</span><span class="p">)</span>
<span class="n">julia</span> <span class="o">=</span> <span class="nc">Subscriber</span><span class="p">(</span><span class="sh">'</span><span class="s">Julia</span><span class="sh">'</span><span class="p">)</span>
<span class="n">jaime</span> <span class="o">=</span> <span class="nc">Subscriber</span><span class="p">(</span><span class="sh">'</span><span class="s">Jaime</span><span class="sh">'</span><span class="p">)</span>

<span class="n">pub</span><span class="p">.</span><span class="nf">register</span><span class="p">(</span><span class="n">juan</span><span class="p">)</span>
<span class="n">pub</span><span class="p">.</span><span class="nf">register</span><span class="p">(</span><span class="n">julia</span><span class="p">)</span>
<span class="n">pub</span><span class="p">.</span><span class="nf">register</span><span class="p">(</span><span class="n">jaime</span><span class="p">)</span>

<span class="n">pub</span><span class="p">.</span><span class="nf">dispatch</span><span class="p">(</span><span class="sh">"</span><span class="s">It</span><span class="sh">'</span><span class="s">s lunchtime!</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Juan got message "It's lunchtime!"
Julia got message "It's lunchtime!"
Jaime got message "It's lunchtime!"
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pub</span><span class="p">.</span><span class="nf">unregister</span><span class="p">(</span><span class="n">juan</span><span class="p">)</span>

<span class="n">pub</span><span class="p">.</span><span class="nf">dispatch</span><span class="p">(</span><span class="sh">"</span><span class="s">Time for dinner</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Julia got message "Time for dinner"
Jaime got message "Time for dinner"
</code></pre></div></div>

<p>This is another simple pattern that can go a long way and not difficult to understand and implement.</p>

<p>If you have any comments or questions feel free to reach out on twitter at <a href="https://twitter.com/fcastellanos">@fcastellanos</a>.</p>

<p>Happy Coding!</p>]]></content><author><name>Fernando Castellanos</name></author><category term="design patterns" /><category term="software patterns" /><category term="best practices" /><category term="observer" /><summary type="html"><![CDATA[This the third part of the Software Design Patterns series, in this post I’m going to talk about the Observer Pattern. This pattern is not exactly the same as the Publisher/Subscriber pattern but is very similar in the way that we have a publisher instance that publishes messages and we also have subscribers that are subscribed to the publisher’s messages.]]></summary></entry><entry><title type="html">Software Design Patterns (Factory)</title><link href="https://fcastellanos.io/2020/07/25/software-design-patterns-factory/" rel="alternate" type="text/html" title="Software Design Patterns (Factory)" /><published>2020-07-25T10:14:52-07:00</published><updated>2020-07-25T10:14:52-07:00</updated><id>https://fcastellanos.io/2020/07/25/software-design-patterns-factory</id><content type="html" xml:base="https://fcastellanos.io/2020/07/25/software-design-patterns-factory/"><![CDATA[<p>In this next post from the Software Design Patterns I’ll talk about one of my favorite patterns which is the Factory pattern, this pattern allows you to create objects without exposing the class directly or its functionality and you interact with the object through a common behavior called an interface.</p>

<p>This pattern is great because it reduces complexity when you need to instantiate objects which have the same behavior so you can focus the business side of the application.</p>

<p>Here’s an example.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Animal</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="n">html</span> <span class="o">=</span> <span class="sh">""</span>
    <span class="k">def</span> <span class="nf">make_sound</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="n">html</span>

<span class="k">class</span> <span class="nc">Cat</span><span class="p">(</span><span class="n">Animal</span><span class="p">):</span>
    <span class="n">html</span> <span class="o">=</span> <span class="sh">"</span><span class="s">meow meow</span><span class="sh">"</span>

<span class="k">class</span> <span class="nc">Dog</span><span class="p">(</span><span class="n">Animal</span><span class="p">):</span>
    <span class="n">html</span> <span class="o">=</span> <span class="sh">"</span><span class="s">woof woof</span><span class="sh">"</span>

<span class="k">class</span> <span class="nc">Lion</span><span class="p">(</span><span class="n">Animal</span><span class="p">):</span>
    <span class="n">html</span> <span class="o">=</span> <span class="sh">"</span><span class="s">roaaaaar</span><span class="sh">"</span>

<span class="k">class</span> <span class="nc">AnimalFactory</span><span class="p">():</span>
    <span class="k">def</span> <span class="nf">create_animal</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">typ</span><span class="p">):</span>
        <span class="n">targetclass</span> <span class="o">=</span> <span class="n">typ</span><span class="p">.</span><span class="nf">capitalize</span><span class="p">()</span>
        <span class="k">return</span> <span class="nf">globals</span><span class="p">()[</span><span class="n">targetclass</span><span class="p">]()</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">Animal</code> class will act as the interface or the behavior for the <code class="language-plaintext highlighter-rouge">Cat</code>, <code class="language-plaintext highlighter-rouge">Dog</code> and <code class="language-plaintext highlighter-rouge">Lion</code> classes which are technically inheriting the behavior from <code class="language-plaintext highlighter-rouge">Animal</code>, in this case all classes inheriting from  <code class="language-plaintext highlighter-rouge">Animal</code> all will have the <code class="language-plaintext highlighter-rouge">make_sound</code> function. Now for the good stuff, the <code class="language-plaintext highlighter-rouge">AnimalFactory</code> class will be the one responsible for instantiating the <code class="language-plaintext highlighter-rouge">Cat</code>, <code class="language-plaintext highlighter-rouge">Dog</code> and <code class="language-plaintext highlighter-rouge">Lion</code> classes.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">animal_factory</span> <span class="o">=</span> <span class="nc">AnimalFactory</span><span class="p">()</span>
<span class="n">animals</span> <span class="o">=</span> <span class="p">[</span><span class="sh">'</span><span class="s">cat</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">dog</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">lion</span><span class="sh">'</span><span class="p">]</span>
<span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">animals</span><span class="p">:</span>
    <span class="n">animal_instance</span> <span class="o">=</span> <span class="n">animal_factory</span><span class="p">.</span><span class="nf">create_animal</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">animal_instance</span><span class="p">.</span><span class="nf">make_sound</span><span class="p">())</span>
</code></pre></div></div>

<p>And the result should be this</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>meow meow
woof woof
roaaaaar
</code></pre></div></div>

<p>If you see you don’t really know what class the <code class="language-plaintext highlighter-rouge">animal_instance</code> belongs to, you just know that it should have a <code class="language-plaintext highlighter-rouge">make_sound</code> function.</p>

<p>And that’s it, this is a simple but a very powerful pattern that it does not take a lot of effort to start using it.</p>

<p>If you have any comments or questions feel free to reach out on twitter at <a href="https://twitter.com/fcastellanos">@fcastellanos</a>.</p>

<p>Happy Coding!</p>]]></content><author><name>Fernando Castellanos</name></author><category term="design patterns" /><category term="software patterns" /><category term="best practices" /><category term="factory" /><summary type="html"><![CDATA[In this next post from the Software Design Patterns I’ll talk about one of my favorite patterns which is the Factory pattern, this pattern allows you to create objects without exposing the class directly or its functionality and you interact with the object through a common behavior called an interface.]]></summary></entry></feed>