<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Blog entries tagged rails :: mwop.net</title>
  <updated>2014-06-09T12:00:00-05:00</updated>
  <generator uri="https://getlaminas.org" version="2">Laminas_Feed_Writer</generator>
  <link rel="alternate" type="text/html" href="https://mwop.net/blog/tag/rails"/>
  <link rel="self" type="application/atom+xml" href="https://mwop.net/blog/tag/rails/atom.xml"/>
  <id>https://mwop.net/blog/tag/rails</id>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Better Understanding Controllers Through Basic Patterns]]></title>
    <published>2014-06-09T12:00:00-05:00</published>
    <updated>2014-06-09T12:00:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2014-06-09-controllers-as-facades.html"/>
    <id>https://mwop.net/blog/2014-06-09-controllers-as-facades.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p><xhtml:a href="http://paul-m-jones.com/">Paul M. Jones</xhtml:a> has started
an interesting discussion rethinking the <xhtml:a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">
MVC</xhtml:a> pattern as applied to the web, which he has dubbed <xhtml:a href="https://github.com/pmjones/mvc-refinement">Action-Domain-Responder
(ADR)</xhtml: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.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml:p>Controllers — Actions in ADR — can be explained as
<xhtml:em>facades</xhtml:em>.</xhtml:p>
<xhtml:h2>Definitions</xhtml:h2>
<xhtml:p>The design pattern <xhtml:em>Facade</xhtml:em> originates in the book
"Design Patterns: Elements of Reusable Object Oriented Software,"
written by Erich Gamma, Ralph Johnson, Richard Helm, and John
Vlissides. Over the years, that book has come to be referred to as
the "Gang of Four", referring to the four authors, and often
abbreviated as "GoF".</xhtml:p>
<xhtml: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 <xhtml:em>relationships</xhtml:em>
between classes or objects in a system. Specifically:</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Facade defines a simplifed interface to a complex system.</xhtml:p>
</xhtml:blockquote>
<xhtml:p><xhtml:a href="http://en.wikipedia.org/wiki/Facade_pattern">Wikipedia
has a general entry on the pattern</xhtml:a> as well, and provides some
other general characteristics of a Facade:</xhtml:p>
<xhtml:ul>
<xhtml:li>A Facade creates a convenience method around a set of
operations, thus reducing the complexity of operations.</xhtml:li>
<xhtml:li>A Facade reduces the immediate dependencies of the calling code
(they call the Facade, not the underlying code).</xhtml:li>
</xhtml:ul>
<xhtml:h2>Facade Example</xhtml:h2>
<xhtml:p>As an example, let's consider the following workflow:</xhtml:p>
<xhtml:ul>
<xhtml:li>Marshal some objects</xhtml:li>
<xhtml:li>Munge some incoming data</xhtml:li>
<xhtml:li>Call a validator</xhtml:li>
<xhtml:li>If the data does not validate, raise an error</xhtml:li>
<xhtml:li>Start a transaction</xhtml:li>
<xhtml:li>Pass data to several different tables</xhtml:li>
<xhtml:li>Commit the transaction</xhtml:li>
<xhtml:li>Log the changes</xhtml:li>
<xhtml:li>Email notifications</xhtml:li>
</xhtml:ul>
<xhtml:p>Now, we could just write the code:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php">$db     = <xhtml:span class="hljs-keyword">new</xhtml:span> Db($connectionConfig);
$log    = <xhtml:span class="hljs-keyword">new</xhtml:span> Logger($loggerConfig);
$mailer = <xhtml:span class="hljs-keyword">new</xhtml:span> Mailer($mailerConfig);
$data   = array_merge_recursive($_POST, $_FILES);

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

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

$log-&gt;info(<xhtml:span class="hljs-string">'Finished a transaction'</xhtml:span>);
$mailer-&gt;send(<xhtml:span class="hljs-string">'New transaction'</xhtml:span>)
</xhtml:code></xhtml:pre>
<xhtml: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.</xhtml:p>
<xhtml:p>A facade would wrap this logic:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">DataTransaction</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">protected</xhtml:span> $db;
    <xhtml:span class="hljs-keyword">protected</xhtml:span> $logger;
    <xhtml:span class="hljs-keyword">protected</xhtml:span> $mailer;

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

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

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

        <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;logger-&gt;info(<xhtml:span class="hljs-string">'Finished a transaction'</xhtml:span>);
        <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;mailer-&gt;send(<xhtml:span class="hljs-string">'New transaction'</xhtml:span>)
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>You would then instantiate the facade — likely using an <xhtml:a href="http://en.wikipedia.org/wiki/Inversion_of_control">Inversion of
Control</xhtml:a> container to inject the dependencies — and then invoke
it:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php">$dataTransaction-&gt;execute(array_merge_recursive($_POST, $_FILES));
</xhtml:code></xhtml:pre>
<xhtml: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.</xhtml:p>
<xhtml:h2>Controllers and Actions</xhtml:h2>
<xhtml:p>Hopefully you can see where I'm going with this.</xhtml:p>
<xhtml:blockquote>
<xhtml:p>Controllers in MVC, and Actions in ADR, are best characterized
as Facades.</xhtml:p>
</xhtml:blockquote>
<xhtml:p>You can define Controllers or Actions as Facades for the
following operations:</xhtml:p>
<xhtml:ul>
<xhtml:li>Marshaling arguments from the request.</xhtml:li>
<xhtml:li>Invoking any domain/model logic, using arguments marshaled from
the request.</xhtml:li>
<xhtml:li>Marshaling and returning a response/responder.</xhtml:li>
</xhtml:ul>
<xhtml:p>I think characterizing Controllers and Actions as Facades has
some huge benefits. In both <xhtml:a href="http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html">
PHP</xhtml:a> and <xhtml:a href="https://www.google.com/search?q=fat+controllers+rails">Rails</xhtml:a>,
we've witnessed the problems that arise from so-called "Fat
Controllers" — 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:</xhtml:p>
<xhtml:ul>
<xhtml:li>Adherence to the <xhtml:a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single
Responsibility Principle</xhtml:a></xhtml:li>
<xhtml:li>Adherence to the <xhtml:a href="http://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency
Inversion Priniciple</xhtml:a></xhtml:li>
<xhtml:li>Adherence to the <xhtml:a href="http://en.wikipedia.org/wiki/Law_Of_Demeter">Law of
Demeter</xhtml:a></xhtml:li>
<xhtml:li>Ability to unit test our Controllers and Actions (instead of
requiring integration tests with complex configuration and
setup)</xhtml:li>
<xhtml:li>The possibility of <xhtml:a href="http://en.wikipedia.org/wiki/Hierarchical_model%E2%80%93view%E2%80%93controller">
hierarchical MVC</xhtml:a> (usually tacked on, or poorly
implemented)</xhtml:li>
<xhtml:li>Clarity of purpose when creating Controllers and Actions (do
only those three things)</xhtml:li>
</xhtml:ul>
<xhtml:p>Defining them as Facades for these three specific operations
means we push logic into specific domains, achieving a proper
<xhtml:a href="http://en.wikipedia.org/wiki/Separation_of_concerns">separation of
concerns</xhtml:a>. Anything that falls outside those three operations
gets pushed elsewhere:</xhtml:p>
<xhtml:ul>
<xhtml: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.</xhtml:li>
<xhtml: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).</xhtml:li>
</xhtml:ul>
<xhtml:p>For me, thinking of Controllers and Actions as Facades has an
additional benefit: it describes rather complex
<xhtml:em>architectural</xhtml:em> patterns in terms of <xhtml:em>basic design
patterns</xhtml:em>. I find the more I can reduce the complexity of a
definition, the more likely I will understand and use it
correctly.</xhtml:p>
<xhtml:h3>Epilogue</xhtml:h3>
<xhtml:p>Consider this post a <xhtml:em>refinement</xhtml:em> of the MVC and ADR
architectural patterns — a way of describing them in terms of more
fundamental design patterns.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml: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</xhtml:a> was originally
published <xhtml:time class="dt-published" datetime="2014-06-09T12:00:00-05:00">9 June 2014</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[DHH on PHP]]></title>
    <published>2008-04-04T09:06:14-05:00</published>
    <updated>2008-04-10T15:45:53-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/168-DHH-on-PHP.html"/>
    <id>https://mwop.net/blog/168-DHH-on-PHP.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>Somebody on <xhtml:a href="http://twitter.com/">Twitter</xhtml:a> pointed
this out, and I thought I'd spread the word: <xhtml:a href="http://www.loudthinking.com/">DHH</xhtml:a> of <xhtml:a href="http://rubyonrails.org/">Rails fame</xhtml:a> has posted a nice, short,
and very interesting thought on <xhtml:a href="http://www.loudthinking.com/posts/23-the-immediacy-of-php">"The
immediacy of PHP"</xhtml:a>.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/168-DHH-on-PHP.html">DHH on PHP</xhtml:a> was
originally published <xhtml:time class="dt-published" datetime="2008-04-04T09:06:14-05:00">4 April 2008</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
</feed>
