<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <title>Blog entries tagged rails :: mwop.net</title>
    <description>Blog entries tagged rails :: mwop.net</description>
    <pubDate>Mon, 09 Jun 2014 12:00:00 -0500</pubDate>
    <generator>Laminas_Feed_Writer 2 (https://getlaminas.org)</generator>
    <link>https://mwop.net/blog/tag/rails</link>
    <atom:link rel="self" type="application/rss+xml" href="https://mwop.net/blog/tag/rails/rss.xml"/>
    <item>
      <title>Better Understanding Controllers Through Basic Patterns</title>
      <pubDate>Mon, 09 Jun 2014 12:00:00 -0500</pubDate>
      <link>https://mwop.net/blog/2014-06-09-controllers-as-facades.html</link>
      <guid>https://mwop.net/blog/2014-06-09-controllers-as-facades.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p><a href="http://paul-m-jones.com/">Paul M. Jones</a> has started an interesting discussion
rethinking the
<a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a>
pattern as applied to the web, which he has dubbed <a href="https://github.com/pmjones/mvc-refinement">Action-Domain-Responder (ADR)</a>.
If you haven't given it a read yet, click the link and do that; this page will
still be sitting here waiting when you return.</p>
<p>I agree with a ton of it — heck, I've contributed to it a fair bit via
conversations with Paul. But there's been one thing nagging at me for a bit
now, and I was finally able to put it into words recently.</p>
<p>Controllers — Actions in ADR — can be explained as <em>facades</em>.</p>


<h2>Definitions</h2>
<p>The design pattern <em>Facade</em> originates in the book &quot;Design Patterns: Elements
of Reusable Object Oriented Software,&quot; written by Erich Gamma, Ralph Johnson,
Richard Helm, and John Vlissides. Over the years, that book has come to be
referred to as the &quot;Gang of Four&quot;, referring to the four authors, and often
abbreviated as &quot;GoF&quot;.</p>
<p>The Facade pattern itself is one of the seven structural design patterns
defined in the GoF. Structural design patterns are those that provide a
mechanism for defining the <em>relationships</em> between classes or objects in a
system. Specifically:</p>
<blockquote>
<p>Facade defines a simplifed interface to a complex system.</p>
</blockquote>
<p><a href="http://en.wikipedia.org/wiki/Facade_pattern">Wikipedia has a general entry on the pattern</a>
as well, and provides some other general characteristics of a Facade:</p>
<ul>
<li>A Facade creates a convenience method around a set of operations, thus
reducing the complexity of operations.</li>
<li>A Facade reduces the immediate dependencies of the calling code (they call
the Facade, not the underlying code).</li>
</ul>
<h2>Facade Example</h2>
<p>As an example, let's consider the following workflow:</p>
<ul>
<li>Marshal some objects</li>
<li>Munge some incoming data</li>
<li>Call a validator</li>
<li>If the data does not validate, raise an error</li>
<li>Start a transaction</li>
<li>Pass data to several different tables</li>
<li>Commit the transaction</li>
<li>Log the changes</li>
<li>Email notifications</li>
</ul>
<p>Now, we could just write the code:</p>
<pre><code class="language-php hljs php" data-lang="php">$db     = <span class="hljs-keyword">new</span> Db($connectionConfig);
$log    = <span class="hljs-keyword">new</span> Logger($loggerConfig);
$mailer = <span class="hljs-keyword">new</span> Mailer($mailerConfig);
$data   = array_merge_recursive($_POST, $_FILES);

$inputFilter = <span class="hljs-keyword">new</span> InputFilter();
$inputFilter-&gt;setData($data);
<span class="hljs-keyword">if</span> (! $inputFilter-&gt;isValid()) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> DomainException();
}

$db-&gt;transactionStart();
$db-&gt;insertInto(<span class="hljs-comment">/* ... */</span>);
$db-&gt;insertInto(<span class="hljs-comment">/* ... */</span>);
$db-&gt;insertInto(<span class="hljs-comment">/* ... */</span>);
$db-&gt;transactionStop();

$log-&gt;info(<span class="hljs-string">'Finished a transaction'</span>);
$mailer-&gt;send(<span class="hljs-string">'New transaction'</span>)
</code></pre>
<p>Straight-forward. But imagine if you needed to do this more than once. Or if
you wanted to re-use this logic in multiple places in your application. This is
a situation just waiting to go out-of-sync — and one where developers will come
to rely on cut-and-paste for doing it correctly.</p>
<p>A facade would wrap this logic:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DataTransaction</span>
</span>{
    <span class="hljs-keyword">protected</span> $db;
    <span class="hljs-keyword">protected</span> $logger;
    <span class="hljs-keyword">protected</span> $mailer;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span><span class="hljs-params">(Db $db, Logger $logger, Mailer $mailer)</span>
    </span>{
        <span class="hljs-keyword">$this</span>-&gt;db     = $db;
        <span class="hljs-keyword">$this</span>-&gt;logger = $logger;
        <span class="hljs-keyword">$this</span>-&gt;mailer = $mailer;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">execute</span><span class="hljs-params">($data)</span>
    </span>{
        $inputFilter = <span class="hljs-keyword">new</span> InputFilter();
        $inputFilter-&gt;setData($data);
        <span class="hljs-keyword">if</span> (! $inputFilter-&gt;isValid()) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> DomainException();
        }

        <span class="hljs-keyword">$this</span>-&gt;db-&gt;transactionStart();
        <span class="hljs-keyword">$this</span>-&gt;db-&gt;insertInto(<span class="hljs-comment">/* ... */</span>);
        <span class="hljs-keyword">$this</span>-&gt;db-&gt;insertInto(<span class="hljs-comment">/* ... */</span>);
        <span class="hljs-keyword">$this</span>-&gt;db-&gt;insertInto(<span class="hljs-comment">/* ... */</span>);
        <span class="hljs-keyword">$this</span>-&gt;db-&gt;transactionStop();

        <span class="hljs-keyword">$this</span>-&gt;logger-&gt;info(<span class="hljs-string">'Finished a transaction'</span>);
        <span class="hljs-keyword">$this</span>-&gt;mailer-&gt;send(<span class="hljs-string">'New transaction'</span>)
    }
}
</code></pre>
<p>You would then instantiate the facade — likely using an
<a href="http://en.wikipedia.org/wiki/Inversion_of_control">Inversion of Control</a>
container to inject the dependencies — and then invoke it:</p>
<pre><code class="language-php hljs php" data-lang="php">$dataTransaction-&gt;execute(array_merge_recursive($_POST, $_FILES));
</code></pre>
<p>This code fulfills the Facade pattern: we're no longer directly manipulating
dependencies, and we've simplified a complex set of operations to a single,
unified API.</p>
<h2>Controllers and Actions</h2>
<p>Hopefully you can see where I'm going with this.</p>
<blockquote>
<p>Controllers in MVC, and Actions in ADR, are best characterized as Facades.</p>
</blockquote>
<p>You can define Controllers or Actions as Facades for the following operations:</p>
<ul>
<li>Marshaling arguments from the request.</li>
<li>Invoking any domain/model logic, using arguments marshaled from the request.</li>
<li>Marshaling and returning a response/responder.</li>
</ul>
<p>I think characterizing Controllers and Actions as Facades has some huge
benefits. In both
<a href="http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html">PHP</a>
and <a href="https://www.google.com/search?q=fat+controllers+rails">Rails</a>, we've
witnessed the problems that arise from so-called &quot;Fat Controllers&quot; —
controllers that do a ton of work, making them untestable, unreadable,
non-reusable nightmares. If we think of them as Facades, specifically for the
three items noted above, we focus on the specific purpose they fulfill within
the system, giving us:</p>
<ul>
<li>Adherence to the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility Principle</a></li>
<li>Adherence to the <a href="http://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency Inversion Priniciple</a></li>
<li>Adherence to the <a href="http://en.wikipedia.org/wiki/Law_Of_Demeter">Law of Demeter</a></li>
<li>Ability to unit test our Controllers and Actions (instead of requiring integration tests with complex configuration and setup)</li>
<li>The possibility of <a href="http://en.wikipedia.org/wiki/Hierarchical_model%E2%80%93view%E2%80%93controller">hierarchical MVC</a> (usually tacked on, or poorly implemented)</li>
<li>Clarity of purpose when creating Controllers and Actions (do only those three things)</li>
</ul>
<p>Defining them as Facades for these three specific operations means we push
logic into specific domains, achieving a proper
<a href="http://en.wikipedia.org/wiki/Separation_of_concerns">separation of concerns</a>.
Anything that falls outside those three operations gets pushed elsewhere:</p>
<ul>
<li>Models/Domains are invoked with the arguments marshaled from the request. If
you find yourself calling many models, or manipulating the results returned
by models, you need to create Facades in your model/domain layer.</li>
<li>If you find yourself doing lots of work in creating your response, you need
to create a Facade for marshaling the response (in ADR, that would mean
encapsulating more logic in your Responder).</li>
</ul>
<p>For me, thinking of Controllers and Actions as Facades has an additional
benefit: it describes rather complex <em>architectural</em> patterns in terms of
<em>basic design patterns</em>. I find the more I can reduce the complexity of a
definition, the more likely I will understand and use it correctly.</p>
<h3>Epilogue</h3>
<p>Consider this post a <em>refinement</em> of the MVC and ADR architectural patterns — a
way of describing them in terms of more fundamental design patterns.</p>
<p>Also, this article is littered with links. Click them. Read them. Digest them.
Read the books they reference. Design and architectural patterns exist because
developers observed the patterns and gave them names; learn to recognize them
and apply them, at all levels of your application.</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/2014-06-09-controllers-as-facades.html">Better Understanding Controllers Through Basic Patterns</a> was originally
    published <time class="dt-published" datetime="2014-06-09T12:00:00-05:00">9 June 2014</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>DHH on PHP</title>
      <pubDate>Thu, 10 Apr 2008 15:45:53 -0500</pubDate>
      <link>https://mwop.net/blog/168-DHH-on-PHP.html</link>
      <guid>https://mwop.net/blog/168-DHH-on-PHP.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>Somebody on <a href="http://twitter.com/">Twitter</a> pointed this out, and I thought I'd
spread the word: <a href="http://www.loudthinking.com/">DHH</a> of
<a href="http://rubyonrails.org/">Rails fame</a> has posted a nice, short, and very interesting
thought on <a href="http://www.loudthinking.com/posts/23-the-immediacy-of-php">&quot;The immediacy of PHP&quot;</a>.</p>
<p>I've been delving a little into Rails lately myself, and what I find is: use
the right tool for the job. For green-field, self-hosted projects, Rails is not
a bad choice, and offers a very easy way to get your application up and running
quickly. But due to the fact that PHP was built for the web, there are any
number of tasks that are simpler and faster to accomplish using it. Evaluate
your needs carefully, and choose the tool that best addresses them.</p>
<p>It's nice to see leaders of projects like Rails having this same attitude. It's
a breath of fresh air in the competitive market of web development frameworks.</p>




<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/168-DHH-on-PHP.html">DHH on PHP</a> was originally
    published <time class="dt-published" datetime="2008-04-04T09:06:14-05:00">4 April 2008</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
  </channel>
</rss>
