<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Virtuous Code &#187; patterns</title>
	<atom:link href="http://devblog.avdi.org/tag/patterns/feed/" rel="self" type="application/rss+xml" />
	<link>http://devblog.avdi.org</link>
	<description>&#34;The three virtues of a programmer: laziness, impatience, and hubris&#34; -- Larry Wall</description>
	<lastBuildDate>Thu, 23 May 2013 18:31:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Modeling the World with Prototypes</title>
		<link>http://devblog.avdi.org/2012/12/11/modeling-the-world-with-prototypes/</link>
		<comments>http://devblog.avdi.org/2012/12/11/modeling-the-world-with-prototypes/#comments</comments>
		<pubDate>Tue, 11 Dec 2012 14:00:00 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[oo]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://devblog.avdi.org/?p=5560</guid>
		<description><![CDATA[This post started out as the second half of an article on prototype-based OO design for Gregory Brown&#8217;s Practicing Ruby. For an introduction to the prototyped view of the object world, and to follow along on an adventure in making &#8230; <a href="http://devblog.avdi.org/2012/12/11/modeling-the-world-with-prototypes/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><em>This post started out as the second half of an article on prototype-based OO design for Gregory Brown&#8217;s <a href="https://practicingruby.com/">Practicing Ruby</a>. For an introduction to the prototyped view of the object world, and to follow along on an adventure in making Ruby act like a prototype-based language instead of a class-based one, you should go <a href="https://practicingruby.com/articles/shared/xjhovcnfqaui">check out that article</a>. Unlike the Practicing Ruby article, which is more about experimentation, this post focuses on the <a href="http://en.wikipedia.org/wiki/Prototype_pattern">Prototype Pattern</a>—a practical way to simplify your object models while still using classes.</em></p>
<div id="outline-container-1" class="outline-2">
<h2 id="sec-1">A monster menagerie</h2>
<div id="text-1" class="outline-text-2">
<p>Let&#8217;s say we&#8217;re writing a dungeon-crawl-style game in the vein of <a href="http://www.nethack.org/">Nethack</a>. So along with the  rooms and items that we&#8217;d expect to find in a text adventure game, there are also various semi-randomly-generated monsters who periodically confront the hero. Different types of monster have different stats, such as health, speed, and strength. They each have their own types of attack as well.</p>
<p>We&#8217;d also like to be able to load up the list of monster types at run-time, from a user-editable file like this:</p>
<pre class="src src-yaml"><span class="org-variable-name">gnome</span>:
  <span class="org-variable-name">attack_text</span>: hits you with a club!
  <span class="org-variable-name">max_hit_points</span>: 8
  <span class="org-variable-name">strength</span>: 5
  <span class="org-variable-name">speed</span>: 9
<span class="org-variable-name">troll</span>:
  <span class="org-variable-name">attack_text</span>: attacks you with a pickaxe!
  <span class="org-variable-name">max_hit_points</span>: 12
  <span class="org-variable-name">strength</span>: 10
  <span class="org-variable-name">speed</span>: 5
<span class="org-variable-name">rabbit</span>:
  <span class="org-variable-name">attack_text</span>: bites you with sharp, pointy teeth!
  <span class="org-variable-name">max_hit_points</span>: 50
  <span class="org-variable-name">strength</span>: 50
  <span class="org-variable-name">speed</span>: 50</pre>
<p>One way to model different monster types would be like this:</p>
<pre class="src src-ruby"><span class="org-keyword">class</span> <span class="org-type">Monster</span>
  attr_reader <span class="org-constant">:health</span>
  <span class="org-keyword">def</span> <span class="org-function-name">initialize</span>
    <span class="org-variable-name">@health</span> = max_hit_points
  <span class="org-keyword">end</span>
<span class="org-keyword">end</span>

<span class="org-keyword">class</span> <span class="org-type">Gnome</span> &lt; <span class="org-type">Monster</span>
  <span class="org-keyword">def</span> <span class="org-function-name">name</span>
    <span class="org-string">"gnome"</span>
  <span class="org-keyword">end</span>

  <span class="org-keyword">def</span> <span class="org-function-name">attack_text</span>
    <span class="org-string">"attacks you with a pickaxe"</span>
  <span class="org-keyword">end</span>

  <span class="org-keyword">def</span> <span class="org-function-name">max_hit_points</span>
    8
  <span class="org-keyword">end</span>

  <span class="org-keyword">def</span> <span class="org-function-name">strength</span>
    5
  <span class="org-keyword">end</span>

  <span class="org-keyword">def</span> <span class="org-function-name">speed</span>
    9
  <span class="org-keyword">end</span>
<span class="org-keyword">end</span>

g = <span class="org-type">Gnome</span>.new
<span class="org-comment-delimiter"># </span><span class="org-comment">=&gt; #&lt;Gnome:0x00000004020130 @health=8&gt;</span></pre>
<p>Here there is a <code>Monster</code> base class, and a subclass for each type of monster. But this doesn&#8217;t really lend itself to dynamically loading arbitrary monster types from a file, so we look for other approaches.</p>
</div>
</div>
<div id="outline-container-2" class="outline-2">
<h2 id="sec-2">Definitions and instances</h2>
<div id="text-2" class="outline-text-2">
<p>We experiment with one design that uses <code>MonsterDefinition</code> classes to hold the static attributes of different monsters. A <code>MonsterDefinition</code> can be told to <code>#spawn</code> a <code>Monster</code> instance. The <code>Monster</code> instance has a reference back to its definition, as well as an instance-specific health meter (initialized based on the <code>max_hit_points</code> of the <code>MonsterDefinition</code>).</p>
<pre class="src src-ruby"><span class="org-keyword">class</span> <span class="org-type">MonsterDefinition</span>
  attr_accessor <span class="org-constant">:name</span>,
                <span class="org-constant">:attack_text</span>,
                <span class="org-constant">:max_hit_points</span>,
                <span class="org-constant">:strength</span>,
                <span class="org-constant">:speed</span>

  <span class="org-keyword">def</span> <span class="org-function-name">initialize</span>(attributes={})
    attributes.each <span class="org-keyword">do</span> |name, value|
      public_send(<span class="org-string">"</span><span class="org-variable-name">#{name}</span><span class="org-string">="</span>, value)
    <span class="org-keyword">end</span>
  <span class="org-keyword">end</span>

  <span class="org-keyword">def</span> <span class="org-function-name">spawn</span>
    <span class="org-type">Monster</span>.new(<span class="org-variable-name">self</span>)
  <span class="org-keyword">end</span>
<span class="org-keyword">end</span>

<span class="org-keyword">class</span> <span class="org-type">Monster</span>
  attr_reader <span class="org-constant">:definition</span>
  attr_accessor <span class="org-constant">:health</span>

  <span class="org-keyword">def</span> <span class="org-function-name">initialize</span>(definition)
    <span class="org-variable-name">@definition</span> = definition
    <span class="org-variable-name">@health</span> = definition.max_hit_points
  <span class="org-keyword">end</span>
<span class="org-keyword">end</span>

gnome_def = <span class="org-type">MonsterDefinition</span>.new(
  <span class="org-constant">name</span>: <span class="org-string">"gnome"</span>,
  <span class="org-constant">attack_text</span>: <span class="org-string">"attacks you with a pickaxe!"</span>,
  <span class="org-constant">max_hit_points</span>: 8,
  <span class="org-constant">strength</span>: 5,
  <span class="org-constant">speed</span>: 9)

g = gnome_def.spawn
<span class="org-comment-delimiter"># </span><span class="org-comment">=&gt; #&lt;Monster:0x0000000401e268</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@definition=</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">#&lt;MonsterDefinition:0x0000000401e9e8</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@attack_text="attacks you with a pickaxe!",</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@max_hit_points=8,</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@name="gnome",</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@speed=9,</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@strength=5&gt;,</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@health=8&gt;</span></pre>
<p>This approach seems promising. But as we reflect on it, we realize that we&#8217;re probably going to keep adding more of these definition/instance pairs of classes. <code>RoomDefinition</code> / <code>Room</code>, <code>ItemDefinition</code> / <code>Item</code>, etc. This feels like an awful lot of ceremony.</p>
</div>
</div>
<div id="outline-container-3" class="outline-2">
<h2 id="sec-3">Cloning creatures</h2>
<div id="text-3" class="outline-text-2">
<p>Finally, we hit upon using the Prototype Pattern. In this version, there is only one class: <code>Monster</code>. It has slots for both static attributes (like <code>name</code>, and <code>strength</code>), and dynamic attributes like <code>health</code>.</p>
<pre class="src src-ruby"><span class="org-keyword">class</span> <span class="org-type">Monster</span>
  attr_accessor <span class="org-constant">:name</span>,
                <span class="org-constant">:attack_text</span>,
                <span class="org-constant">:max_hit_points</span>,
                <span class="org-constant">:strength</span>,
                <span class="org-constant">:speed</span>,
                <span class="org-constant">:health</span>

  <span class="org-keyword">def</span> <span class="org-function-name">initialize</span>(attributes={})
    attributes.each <span class="org-keyword">do</span> |name, value|
      public_send(<span class="org-string">"</span><span class="org-variable-name">#{name}</span><span class="org-string">="</span>, value)
    <span class="org-keyword">end</span>
  <span class="org-keyword">end</span>

  <span class="org-keyword">def</span> <span class="org-function-name">initialize_dup</span>(prototype)
    <span class="org-variable-name">self</span>.health = prototype.max_hit_points
    <span class="org-keyword">super</span>
  <span class="org-keyword">end</span>

<span class="org-keyword">end</span></pre>
<p>To initialize our game&#8217;s bestiary of possible monster types, we load up the YAML-formatted monster file and initialize a <code>Monster</code> for each entry. Dynamic attributes like <code>health</code> are left blank for now. These are our <em>prototypes</em>.</p>
<pre class="src src-ruby">require <span class="org-string">'yaml'</span>
bestiary = <span class="org-type">YAML</span>.load_file(<span class="org-string">'monsters.yml'</span>).each_with_object({}) <span class="org-keyword">do</span>
  |(name, attributes), collection|
  collection[name] = <span class="org-type">Monster</span>.new(attributes.merge(<span class="org-constant">name</span>: name))
<span class="org-keyword">end</span></pre>
<p>When we want to set up a player encounter with a monster, we simply find the appropriate prototype monster, and duplicate it. The customized <code>#initialize_dup</code> method in <code>Monster</code> takes care of setting up an initial health meter for the cloned monster.</p>
<pre class="src src-ruby">rabbit = bestiary[<span class="org-string">'rabbit'</span>].dup
<span class="org-comment-delimiter"># </span><span class="org-comment">=&gt; #&lt;Monster:0x00000000fbd948</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@attack_text="bites you with sharp, pointy teeth!",</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@max_hit_points=50,</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@name="rabbit",</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@speed=50,</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@strength=50&gt;</span></pre>
<p>we can easily generate random monsters:</p>
<pre class="src src-ruby">random_foe = bestiary.values.sample.dup
<span class="org-comment-delimiter"># </span><span class="org-comment">=&gt; #&lt;Monster:0x00000000fc21f0</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@attack_text="attacks you with a pickaxe!",</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@max_hit_points=12,</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@name="troll",</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@speed=5,</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">@strength=10&gt;</span></pre>
<p>This solution is both shorter and simpler than any of the others we tried.</p>
</div>
</div>
<div id="outline-container-4" class="outline-2">
<h2 id="sec-4">Representing Forms</h2>
<div id="text-4" class="outline-text-2">
<p>The Prototype Pattern is, in my experience, one of the more overlooked of the Gang of Four patterns. It is useful in many situations. As another example, consider a web application where administrators build form templates and then users fill out the forms. One way to model this is to populate the form builder interface <code>FormDefinition</code> objects, containing instances of <code>TextFieldDefinition</code>, <code>CheckboxFieldDefinition</code>, <code>DateFieldDefinition</code>, and so on. Then, when the form definition is complete and ready for user input, a new <code>Form</code> object is created, using the <code>FormDefinition</code> as a guide, with <code>TextField</code>, <code>CheckboxField</code>, <code>DateField</code>, etc. objects &#8220;inside&#8221; of it.</p>
<p style="text-align: center;"><a href="http://devblog.avdi.org/wp-content/uploads/2012/12/wpid-form-classes-800.png"><img class="aligncenter" title="Click to see a full-size version" src="http://devblog.avdi.org/wp-content/uploads/2012/12/wpid-form-classes-800.png" alt="http://devblog.avdi.org/wp-content/uploads/2012/12/wpid-form-classes-800.png" width="432" height="123" /></a></p>
<p>If we apply the Prototype Pattern to this problem, we once again do away with the definition/instance dichotomy. Instead, building a new form simply means assembling a <code>Form</code> object, where all of the form fields have empty or placeholder values. (This makes it exceptionally easy to show a live preview of the form as it is being built). The form is published by turning on a flag marking it as a &#8220;master&#8221; form. Whenever a user fills out the form, they are really filling out a duplicate of the master.</p>
<p style="text-align: center;"><a href="http://devblog.avdi.org/wp-content/uploads/2012/12/wpid-form-prototypes-800.png"><img class="aligncenter" title="Click to see a full-size version" src="http://devblog.avdi.org/wp-content/uploads/2012/12/wpid-form-prototypes-800.png" alt="http://devblog.avdi.org/wp-content/uploads/2012/12/wpid-form-prototypes-800.png" width="432" height="144" /></a></p>
</div>
</div>
<div id="outline-container-5" class="outline-2">
<h2 id="sec-5">Observations</h2>
<div id="text-5" class="outline-text-2">
<p><span style="text-decoration: underline;">Design Patterns</span> says that the Prototype Pattern is appropriate:</p>
<blockquote><p>when a system should be should be independent of how its products are created, composed, and represented, <em>and</em></p>
<ul>
<li>when the classes to instantiate are specified at run-time, for<br />
example, by dynamic loading; <em>or</em></li>
<li>to avoid building a class hierarchy of factories that parallels<br />
the class hierarchy of products; <em>or</em></li>
<li>when instances of a class can have only one of a few different<br />
combinations of state. It may be more convenient to install a<br />
corresponding number of prototypes and clone them rather than<br />
instantiating the class manually, each time with the appropriate<br />
state.</li>
</ul>
</blockquote>
<p>The class-based view vs. the prototype-based view of OO represent a philosophical divide in how we model the world in software. We can learn from both points of view. But the lessons of the prototype-oriented mindset are not merely philosophical ones for users of class-based languages. The Prototype Pattern is a way to apply prototypes in a class-based system, one that can slash through complicated parallel inheritance hierarchies and provide a simple, flexible, and dynamic alternative.</p>
<p>Questions? Comments? Have experience implementing the prototype pattern in your own applications? Pipe up in the comments!</p>
<p>Oh, and do check out <a href="https://practicingruby.com/articles/shared/xjhovcnfqaui">the article I wrote for Practicing Ruby</a>. I had a blast metaprograming Ruby into behaving more like <a href="http://en.wikipedia.org/wiki/Self_(programming_language)">Self</a> :-)</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2012/12/11/modeling-the-world-with-prototypes/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>DisplayCase Gem Now Available</title>
		<link>http://devblog.avdi.org/2012/06/04/displaycase-gem-now-available/</link>
		<comments>http://devblog.avdi.org/2012/06/04/displaycase-gem-now-available/#comments</comments>
		<pubDate>Mon, 04 Jun 2012 13:00:34 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[exhibit]]></category>
		<category><![CDATA[gems]]></category>
		<category><![CDATA[libraries]]></category>
		<category><![CDATA[objects-on-rails]]></category>
		<category><![CDATA[oor]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[Presenter Pattern]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://devblog.avdi.org/?p=2394</guid>
		<description><![CDATA[Announcing the display_case gem, an implementation of the Exhibit pattern described in (and extracted from) "Objects on Rails". <a href="http://devblog.avdi.org/2012/06/04/displaycase-gem-now-available/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>When I set out to write <a href="http://objectsonrails.com">Objects on Rails</a>, I knew I wanted to cover the Presenter pattern. Or at least, what I thought of as the Presenter pattern. So I set out to read up on the history of Presenters in the context of Ruby on Rails applications.</p>
<p>The more I read, the more I realized that what I and possibly others <a href="http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/">had been calling &#8220;Presenter&#8221;</a> was really something a bit different from the idea that Jay Fields first introduced under that name in 2006, and subsequently expanded on. Originally, Presenter was fundamentally an aggregation pattern. The canonical example is a report: you have a view in which data from numerous models is brought together into a single summary view. Rather than have a controller instantiate and/or query numerous models, you group them all into a Presenter object which represents that logical &#8220;screen&#8221; as a single aggregate object.</p>
<p>I won&#8217;t bore you with the details of my research. If you&#8217;re curious, here&#8217;s my Presenter reading list from OoR:</p>
<ul>
<li><a href="http://blog.jayfields.com/2006/09/rails-model-view-controller-presenter.html">Model View Controller + Presenter?</a> - the post that first introduced the Presenter concept.</li>
<li><a href="http://blog.jayfields.com/2007/01/another-rails-presenter-example.html">Another Presenter Example</a></li>
<li><a href="http://blog.jayfields.com/2007/02/rails-presenters-additional-layer.html">Presenters &#8211; An Additional layer example</a>.</li>
<li><a href="http://blog.jayfields.com/2007/03/rails-presenter-pattern.html">Presenter Pattern</a> - a formalization of the pattern.</li>
<li><a href="http://blog.jayfields.com/2007/10/rails-rise-fall-and-potential-rebirth.html">Rise, Fall, and Potential Rebirth of the Presenter Pattern</a>. A retrospective look at the experiences Jay and others had applying Presenters to various projects.</li>
<li>Courtenay Gasking: <a href="http://web.archive.org/web/20100523060851/http://blog.caboo.se/articles/2007/8/23/simple-presenters">Simple Presenters</a>.</li>
<li>Zach Dennis: <a href="http://spin.atomicobject.com/2008/01/27/the-exceptional-presenter/">The Exceptional Presenter</a>.</li>
<li>Dmytro Shteflyuk: <a href="http://kpumuk.info/ruby-on-rails/simplifying-your-ruby-on-rails-code/">Simplifying your Ruby on Rails code: Presenter pattern, cells plugin</a>.</li>
<li>Steve Klabnick: <a href="http://blog.steveklabnik.com/posts/2011-09-09-better-ruby-presenters">Better Ruby Presenters</a>. A follow-up to <a href="http://blog.steveklabnik.com/2011/09/06/the-secret-to-rails-oo-design.html">The Secret to Rails OO Design</a>, referenced earlier.</li>
<li>Jeff Casimir: <a href="http://jumpstartlab.com/news/archives/2011/12/01/blow-up-your-views/">Blow Up Your Views</a>. Jeff encoded the concepts introduced in this presentation in his <a href="https://github.com/jcasimir/draper">Draper</a> gem.</li>
<li>Martin Fowler <a href="http://www.martinfowler.com/eaaDev/uiArchs.html">summarizes GUI patterns</a>. Note: this article is more concerned with rich client-side GUI patterns than web GUIs.</li>
</ul>
<p>By contrast, what I had been using on several projects, and was eager to show people in the book, was more of a presentational decorator. Now I had a quandary: I had already drafted a whole section on them, but now I wasn&#8217;t sure what to call them. &#8220;Decorator&#8221; was too generic for the very specific <em>kind </em>of decorator I was describing. &#8220;Presentational decorator&#8221; didn&#8217;t exactly roll off the tongue.</p>
<p>The presentational pattern I came to describe as an &#8220;exhibit&#8221; in OoR has the following trademarks:</p>
<ul>
<li><strong>It wraps a single model instance. </strong>Not an assortment of objects.</li>
<li><strong>It is a true Decorator</strong>. All unrecognized messages are passed through to the underlying object. This facilitates a gradual migration to the use of Exhibits to encapsulate presentation knowledge, since they can be layered onto models without any change to the existing views. It also enables multiple Exhibits to be layered onto an object, each handling different aspects of presentation.</li>
<li><strong>It brings together a model and a context</strong>. Exhibits need a reference to a &#8220;context&#8221; object—either a controller or a view context—in order to be able to render templates as well as construct URLs for the object or related resources.</li>
<li><strong>It encapsulates decisions about how to render an object.</strong> The tell-tale of an Exhibit is telling an object &#8220;render yourself&#8221;, rather than explicitly rendering a template and passing the object in as an argument.</li>
<li><strong>It <em>may</em> modify the behavior of an object.</strong> For instance, an Exhibit might impose a scope on a <code>Blog#entries</code> association which only returns entries that are visible to the current user (as determined from the Exhibit&#8217;s controller context). Or it might reformat the return value of a <code>#social_security_number</code> method to include dashes and have all but the last four digits obscured: <code>***-**-5678</code>.</li>
<li><span style="color: #000000;"><strong>There is a many-to-many relationship between model classes and exhibit classes.</strong> One generic exhibit class may apply to several different types of model. Other exhibits may be specific, not just to a model, but to a model in a particular state, or within a particular viewing context.</span></li>
</ul>
<p>The more I thought about it, the clearer it seemed that while this idea wasn&#8217;t <em>new</em>&#8211;a number of people were already using similar constructs&#8211;it had sufficient unique traits to perhaps warrant a name of its own. And I was convinced that continuing to call it a &#8220;presenter&#8221; would just make things needlessly confusing. Hence, the term &#8220;exhibit&#8221; was born.</p>
<p>Since I released the book, the Exhibit idea seems to have struck a chord. I get a lot of feedback from people who say they are happily using it in their own projects. In fact, I get more positive feedback about Exhibits than about anything else in the book.</p>
<p><a href="http://devblog.avdi.org/2012/06/04/displaycase-gem-now-available/httpwww-dreamstime-com-image24464369/" rel="attachment wp-att-2395"><img class="alignright size-medium wp-image-2395" title="http://www.dreamstime.com/-image24464369" src="http://devblog.avdi.org/wp-content/uploads/2012/05/dreamstime_s_24464369-300x225.jpg" alt="" width="300" height="225" /></a>While anyone can roll their own Exhibits&#8211;that&#8217;s the point of a pattern, after all&#8211;I fully intended to release the basic Exhibit framework demonstrated in the OoR source code as open-source code. Today, thanks once again to the diligent curation of Sammy Larbi, I&#8217;m happy to announce that this code is available as the <a href="http://rubygems.org/gems/display_case">display_case</a> gem. Of course, it&#8217;s also<a href="https://github.com/objects-on-rails/display-case"> available on GitHub</a> as well.</p>
<p>Why call it &#8220;display_case&#8221; instead of &#8220;exhibit&#8221;? Simply because it&#8217;s a pet peeve of mine to name libraries after patterns. It makes discussing them confusing&#8211;are we talking about the general pattern, or a specific library?</p>
<p>This post has been long enough, so I won&#8217;t go into usage here. You can read all about how to use the gem <a href="https://github.com/objects-on-rails/display-case">on the homepage</a>. And if you have any questions or suggestions, please do join the <a href="https://groups.google.com/d/forum/objects-on-rails">Objects on Rails public discussion list</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2012/06/04/displaycase-gem-now-available/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Making Little Classes out of Big Ones (video)</title>
		<link>http://devblog.avdi.org/2012/05/25/making-little-classes-out-of-big-ones-video/</link>
		<comments>http://devblog.avdi.org/2012/05/25/making-little-classes-out-of-big-ones-video/#comments</comments>
		<pubDate>Fri, 25 May 2012 13:00:05 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Videos]]></category>
		<category><![CDATA[composition]]></category>
		<category><![CDATA[decomposition]]></category>
		<category><![CDATA[decorators]]></category>
		<category><![CDATA[modules]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://devblog.avdi.org/?p=2387</guid>
		<description><![CDATA[I recently visited the Hashrocket offices in Jacksonville, and while I was there I did a Lunch &#38; Learn talk on the topic of of breaking down too-big classes into smaller pieces. In it I went over pros and cons &#8230; <a href="http://devblog.avdi.org/2012/05/25/making-little-classes-out-of-big-ones-video/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<div>I recently visited the <a href="http://hashrocket.com">Hashrocket</a> offices in Jacksonville, and while I was there I did a Lunch &amp; Learn talk on the topic of of breaking down too-big classes into smaller pieces. In it I went over pros and cons of four strategies:</div>
<div></div>
<div>
<ul>
<li><span style="font-size: 12px; line-height: 18px;">Breaking the class into modules</span></li>
<li><span style="font-size: 12px; line-height: 18px;">Decorators</span></li>
<li><span style="font-size: 12px; line-height: 18px;">Dynamic module extension</span></li>
<li><span style="font-size: 12px; line-height: 18px;">Object Composition</span></li>
</ul>
<div>We had a nice long conversation after the talk proper, which is one of the things I like about these more informal talks.</div>
<div></div>
<div>Here&#8217;s the video:</div>
</div>
<p><iframe src="http://player.vimeo.com/video/42622511" width="620" height="349" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
<div>The <a href="https://speakerdeck.com/u/avdi/p/making-little-classes-out-of-big-ones">slides are available</a> as well.</div>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2012/05/25/making-little-classes-out-of-big-ones-video/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Decoration is best, except when it isn&#8217;t</title>
		<link>http://devblog.avdi.org/2012/01/31/decoration-is-best-except-when-it-isnt/</link>
		<comments>http://devblog.avdi.org/2012/01/31/decoration-is-best-except-when-it-isnt/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 14:00:00 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=2002</guid>
		<description><![CDATA[I think by now we all know to prefer composition over inheritance. But in a language with a lot of options, what&#8217;s the best kind of composition to use? Composing an adventure Consider an adventure game, with objects representing player &#8230; <a href="http://devblog.avdi.org/2012/01/31/decoration-is-best-except-when-it-isnt/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I think by now we all know to <a href="http://en.wikipedia.org/wiki/Composition_over_inheritance">prefer composition over inheritance</a>. But in a language with a lot of options, what&#8217;s the best kind of composition to use? </p>
<div id="outline-container-1" class="outline-3">
<h3 id="sec-1">Composing an adventure</h3>
<div class="outline-text-3" id="text-1">
<p> Consider an adventure game, with objects representing player characters. </p>
<pre class="src src-ruby"><span class="org-keyword">class</span><span class="org-whitespace-space"> </span><span class="org-type">Character</span>
<span class="org-whitespace-space">  </span><span class="org-comment-delimiter">#</span><span class="org-whitespace-space"> </span><span class="org-comment">...</span>
<span class="org-keyword">end</span>
</pre>
<p> A <code>Character</code> can be described: </p>
<pre class="src src-ruby"><span class="org-keyword">class</span><span class="org-whitespace-space"> </span><span class="org-type">Character</span>
<span class="org-whitespace-space">  </span><span class="org-comment-delimiter">#</span><span class="org-whitespace-space"> </span><span class="org-comment">...</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">describe</span>
<span class="org-whitespace-space">    </span>puts<span class="org-whitespace-space"> </span><span class="org-string">"You</span><span class="org-whitespace-space"> </span><span class="org-string">are</span><span class="org-whitespace-space"> </span><span class="org-string">a</span><span class="org-whitespace-space"> </span><span class="org-string">dashing,</span><span class="org-whitespace-space"> </span><span class="org-string">rugged</span><span class="org-whitespace-space"> </span><span class="org-string">adventurer."</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>
<span class="org-whitespace-space">  </span><span class="org-comment-delimiter">#</span><span class="org-whitespace-space"> </span><span class="org-comment">...</span>
<span class="org-keyword">end</span>
</pre>
<p> A <code>Character</code> can look, listen, and smell his environment: </p>
<pre class="src src-ruby"><span class="org-keyword">class</span><span class="org-whitespace-space"> </span><span class="org-type">Character</span>
<span class="org-whitespace-space">  </span><span class="org-comment-delimiter">#</span><span class="org-whitespace-space"> </span><span class="org-comment">...</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">look</span>
<span class="org-whitespace-space">    </span>list(<span class="org-string">"You</span><span class="org-whitespace-space"> </span><span class="org-string">can</span><span class="org-whitespace-space"> </span><span class="org-string">see"</span>,<span class="org-whitespace-space"> </span>[<span class="org-string">"a</span><span class="org-whitespace-space"> </span><span class="org-string">lightning</span><span class="org-whitespace-space"> </span><span class="org-string">bug"</span>,<span class="org-whitespace-space"> </span><span class="org-string">"a</span><span class="org-whitespace-space"> </span><span class="org-string">guttering</span><span class="org-whitespace-space"> </span><span class="org-string">candle"</span>])
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>

<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">listen</span>
<span class="org-whitespace-space">    </span>list(<span class="org-string">"You</span><span class="org-whitespace-space"> </span><span class="org-string">hear"</span>,<span class="org-whitespace-space"> </span>[<span class="org-string">"a</span><span class="org-whitespace-space"> </span><span class="org-string">distant</span><span class="org-whitespace-space"> </span><span class="org-string">waterfall"</span>])
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>

<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">smell</span>
<span class="org-whitespace-space">    </span>list(<span class="org-string">"You</span><span class="org-whitespace-space"> </span><span class="org-string">smell"</span>,<span class="org-whitespace-space"> </span>[<span class="org-string">"egg</span><span class="org-whitespace-space"> </span><span class="org-string">salad"</span>])
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>

<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">list</span>(prefix,<span class="org-whitespace-space"> </span>objects)
<span class="org-whitespace-space">    </span>objects.each<span class="org-whitespace-space"> </span><span class="org-keyword">do</span><span class="org-whitespace-space"> </span>|o|
<span class="org-whitespace-space">      </span>puts<span class="org-whitespace-space"> </span><span class="org-string">"</span><span class="org-variable-name">#{prefix}</span><span class="org-whitespace-space"> </span><span class="org-variable-name">#{o}</span><span class="org-string">."</span>
<span class="org-whitespace-space">    </span><span class="org-keyword">end</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>
<span class="org-whitespace-space">  </span><span class="org-comment-delimiter">#</span><span class="org-whitespace-space"> </span><span class="org-comment">...</span>
<span class="org-keyword">end</span>
</pre>
<pre class="src src-ruby">require<span class="org-whitespace-space"> </span><span class="org-string">'./decoration-vs-extension'</span>
cohen<span class="org-whitespace-space"> </span>=<span class="org-whitespace-space"> </span><span class="org-type">Character</span>.new
cohen.describe
cohen.look
cohen.listen
</pre>
<pre class="example">
You are a dashing, rugged adventurer.
You can see a lightning bug.
You can see a guttering candle.
You hear a distant waterfall.
</pre>
<p> The character can also consult all of his senses at once: </p>
<pre class="src src-ruby"><span class="org-keyword">class</span><span class="org-whitespace-space"> </span><span class="org-type">Character</span>
<span class="org-whitespace-space">  </span><span class="org-comment-delimiter">#</span><span class="org-whitespace-space"> </span><span class="org-comment">...</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">observe</span>
<span class="org-whitespace-space">    </span>look
<span class="org-whitespace-space">    </span>listen
<span class="org-whitespace-space">    </span>smell
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>
<span class="org-whitespace-space">  </span><span class="org-comment-delimiter">#</span><span class="org-whitespace-space"> </span><span class="org-comment">...</span>
<span class="org-keyword">end</span>
</pre>
<pre class="src src-ruby">require<span class="org-whitespace-space"> </span><span class="org-string">'./decoration-vs-extension'</span>
cohen<span class="org-whitespace-space"> </span>=<span class="org-whitespace-space"> </span><span class="org-type">Character</span>.new
cohen.observe
</pre>
<pre class="example">
You can see a lightning bug.
You can see a guttering candle.
You hear a distant waterfall.
You smell egg salad.
</pre>
<p> Characters can have various effects conferred upon them by items, potions, etc. A simple example is a hat: </p>
<pre class="src src-ruby">require<span class="org-whitespace-space"> </span><span class="org-string">'delegate'</span>
<span class="org-keyword">class</span><span class="org-whitespace-space"> </span><span class="org-type">BowlerHatDecorator</span><span class="org-whitespace-space"> </span>&lt;<span class="org-whitespace-space"> </span><span class="org-type">SimpleDelegator</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">describe</span>
<span class="org-whitespace-space">    </span><span class="org-keyword">super</span>
<span class="org-whitespace-space">    </span>puts<span class="org-whitespace-space"> </span><span class="org-string">"A</span><span class="org-whitespace-space"> </span><span class="org-string">jaunty</span><span class="org-whitespace-space"> </span><span class="org-string">bowler</span><span class="org-whitespace-space"> </span><span class="org-string">cap</span><span class="org-whitespace-space"> </span><span class="org-string">sits</span><span class="org-whitespace-space"> </span><span class="org-string">atop</span><span class="org-whitespace-space"> </span><span class="org-string">your</span><span class="org-whitespace-space"> </span><span class="org-string">head."</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>
<span class="org-keyword">end</span>
</pre>
<p> At each turn of the game, the <code>Character</code> object will be decorated with whatever effects are currently active, and then a user command will be performed: </p>
<pre class="src src-ruby">require<span class="org-whitespace-space"> </span><span class="org-string">'./decoration-vs-extension'</span>
cohen<span class="org-whitespace-space"> </span>=<span class="org-whitespace-space"> </span><span class="org-type">BowlerHatDecorator</span>.new(<span class="org-type">Character</span>.new)
cohen.describe
</pre>
<pre class="example">
You are a dashing, rugged adventurer.
A jaunty bowler cap sits atop your head.
</pre>
</p></div>
</p></div>
<div id="outline-container-2" class="outline-3">
<h3 id="sec-2">Seeing in the dark</h3>
<div class="outline-text-3" id="text-2">
<p> A more interesting effect is conferred by an infravision potion. It enables your character to see in the dark. </p>
<pre class="src src-ruby"><span class="org-keyword">class</span><span class="org-whitespace-space"> </span><span class="org-type">InfravisionPotionDecorator</span><span class="org-whitespace-space"> </span>&lt;<span class="org-whitespace-space"> </span><span class="org-type">SimpleDelegator</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">describe</span>
<span class="org-whitespace-space">    </span><span class="org-keyword">super</span>
<span class="org-whitespace-space">    </span>puts<span class="org-whitespace-space"> </span><span class="org-string">"Your</span><span class="org-whitespace-space"> </span><span class="org-string">eyes</span><span class="org-whitespace-space"> </span><span class="org-string">glow</span><span class="org-whitespace-space"> </span><span class="org-string">dull</span><span class="org-whitespace-space"> </span><span class="org-string">red."</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>

<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">look</span>
<span class="org-whitespace-space">    </span><span class="org-keyword">super</span>
<span class="org-whitespace-space">    </span>look_infrared
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>

<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">look_infrared</span>
<span class="org-whitespace-space">    </span>list(<span class="org-string">"You</span><span class="org-whitespace-space"> </span><span class="org-string">can</span><span class="org-whitespace-space"> </span><span class="org-string">see"</span>,<span class="org-whitespace-space"> </span>[<span class="org-string">"the</span><span class="org-whitespace-space"> </span><span class="org-string">ravenous</span><span class="org-whitespace-space"> </span><span class="org-string">bugblatter</span><span class="org-whitespace-space"> </span><span class="org-string">beast</span><span class="org-whitespace-space"> </span><span class="org-string">of</span><span class="org-whitespace-space"> </span><span class="org-string">traal"</span>])
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>
<span class="org-keyword">end</span>
</pre>
<p> While the character is experiencing the effects of an <a href="http://nethack.wikia.com/wiki/Infravision">infravision</a> potion, his powers of observation increase: </p>
<pre class="src src-ruby">require<span class="org-whitespace-space"> </span><span class="org-string">'./decoration-vs-extension'</span>
cohen<span class="org-whitespace-space"> </span>=<span class="org-whitespace-space"> </span><span class="org-type">InfravisionPotionDecorator</span>.new(<span class="org-type">Character</span>.new)
cohen.describe
cohen.look
</pre>
<pre class="example">
You are a dashing, rugged adventurer.
Your eyes glow dull red.
You can see a lightning bug.
You can see a guttering candle.
You can see the ravenous bugblatter beast of traal.
</pre>
<p> There&#8217;s just one little problem that crops up when the <code>#observe</code> method is called. </p>
<pre class="src src-ruby">require<span class="org-whitespace-space"> </span><span class="org-string">'./decoration-vs-extension'</span>
cohen<span class="org-whitespace-space"> </span>=<span class="org-whitespace-space"> </span><span class="org-type">InfravisionPotionDecorator</span>.new(<span class="org-type">Character</span>.new)
cohen.observe
</pre>
<pre class="example">
You can see a lightning bug.
You can see a guttering candle.
You hear a distant waterfall.
You smell egg salad.
</pre>
<p> Hey, where&#8217;d that bugblatter beast go? </p>
<p> The <code>Character#observe</code> method calls <code>#look</code>&mdash;but since the wrapped object has no knowledge whatsoever of the <code>InfravisionPotionDecorator</code>, it calls the original definition of <code>#look</code>, not the one which also calls <code>#look_infrared</code>. </p>
<p> Now, granted, this flaw actually works out in our intrepid adventurer&#8217;s favor, since the ravenous bugblatter beast of Traal is so stupid it thinks that if you can&#8217;t see it, it can&#8217;t see you. But never mind that: it&#8217;s still a bug, and bugs must be blattered. </p>
</p></div>
</p></div>
<div id="outline-container-3" class="outline-3">
<h3 id="sec-3">A solution that&#8217;s all wet</h3>
<div class="outline-text-3" id="text-3">
<p> We could patch this flaw by overriding <code>#observe</code> as well in the decorator: </p>
<pre class="src src-ruby"><span class="org-keyword">class</span><span class="org-whitespace-space"> </span><span class="org-type">InfravisionPotionDecorator</span><span class="org-whitespace-space"> </span>&lt;<span class="org-whitespace-space"> </span><span class="org-type">SimpleDelegator</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">observe</span>
<span class="org-whitespace-space">    </span>look
<span class="org-whitespace-space">    </span>listen
<span class="org-whitespace-space">    </span>smell
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>
<span class="org-keyword">end</span>
</pre>
<p> Yuck! This is the exact same implementation as in <code>Character</code>, just copied and pasted so that the correct implementaiton of <code>#look</code> will be called. Clearly this is non-DRY. But even worse, we&#8217;ve introduced a nasty variety of <a href="http://blog.rubybestpractices.com/posts/gregory/056-issue-24-connascence.html">connascence</a>. Every time we introduces a new <code>Character</code> method which calls <code>#look</code>, we&#8217;ll have to cull through every single effect decorator which overrides <code>#look</code>, adding copy-and-pasted versions of the new method so that it doesn&#8217;t accidentally ignore the effect-wrapped version. Double yuck! </p>
</p></div>
</p></div>
<div id="outline-container-4" class="outline-3">
<h3 id="sec-4">Modules to the rescue</h3>
<div class="outline-text-3" id="text-4">
<p> In Ruby, there is an easy solution: extend the character with a module instead of a decorator. </p>
<pre class="src src-ruby"><span class="org-keyword">module</span><span class="org-whitespace-space"> </span><span class="org-type">InfravisionPotionModule</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">describe</span>
<span class="org-whitespace-space">    </span><span class="org-keyword">super</span>
<span class="org-whitespace-space">    </span>puts<span class="org-whitespace-space"> </span><span class="org-string">"Your</span><span class="org-whitespace-space"> </span><span class="org-string">eyes</span><span class="org-whitespace-space"> </span><span class="org-string">glow</span><span class="org-whitespace-space"> </span><span class="org-string">dull</span><span class="org-whitespace-space"> </span><span class="org-string">red."</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>

<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">look</span>
<span class="org-whitespace-space">    </span><span class="org-keyword">super</span>
<span class="org-whitespace-space">    </span>look_infrared
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>

<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">look_infrared</span>
<span class="org-whitespace-space">    </span>list(<span class="org-string">"You</span><span class="org-whitespace-space"> </span><span class="org-string">can</span><span class="org-whitespace-space"> </span><span class="org-string">see"</span>,<span class="org-whitespace-space"> </span>[<span class="org-string">"the</span><span class="org-whitespace-space"> </span><span class="org-string">ravenous</span><span class="org-whitespace-space"> </span><span class="org-string">bugblatter</span><span class="org-whitespace-space"> </span><span class="org-string">beast</span><span class="org-whitespace-space"> </span><span class="org-string">of</span><span class="org-whitespace-space"> </span><span class="org-string">traal"</span>])
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>
<span class="org-keyword">end</span>
</pre>
<pre class="src src-ruby">require<span class="org-whitespace-space"> </span><span class="org-string">'./decoration-vs-extension'</span>
cohen<span class="org-whitespace-space"> </span>=<span class="org-whitespace-space"> </span><span class="org-type">Character</span>.new.extend(<span class="org-type">InfravisionPotionModule</span>)
cohen.observe
</pre>
<pre class="example">
You can see a lightning bug.
You can see a guttering candle.
You can see the ravenous bugblatter beast of traal.
You hear a distant waterfall.
You smell egg salad.
</pre>
<p> This time the overridden method is added directly to the object via its singleton class. So even the object&#8217;s own unmodified methods get the new infravision version of <code>#look</code>. </p>
<p> Sadly, by enabling him to see the monster we have sealed our protagonists&#8217;s fate. But at least we fixed the bug! </p>
</p></div>
</p></div>
<div id="outline-container-5" class="outline-3">
<h3 id="sec-5">Other solutions</h3>
<div class="outline-text-3" id="text-5">
<p> That&#8217;s not the only way to fix the problem. We might, for instance, decompose our <code>Character</code> into individual body parts, with separate attributes for <code>eyes</code>, <code>nose</code>, and <code>ears</code>. The <code>Character</code> could then delegate the individual senses to their respective organs: </p>
<pre class="src src-ruby">require<span class="org-whitespace-space"> </span><span class="org-string">'forwardable'</span>
<span class="org-keyword">class</span><span class="org-whitespace-space"> </span><span class="org-type">Character</span>
<span class="org-whitespace-space">  </span>extend<span class="org-whitespace-space"> </span><span class="org-type">Forwardable</span>

<span class="org-whitespace-space">  </span>attr_accessor<span class="org-whitespace-space"> </span><span class="org-constant">:eyes</span>
<span class="org-whitespace-space">  </span>attr_accessor<span class="org-whitespace-space"> </span><span class="org-constant">:ears</span>
<span class="org-whitespace-space">  </span>attr_accessor<span class="org-whitespace-space"> </span><span class="org-constant">:nose</span>

<span class="org-whitespace-space">  </span>def_delegator<span class="org-whitespace-space"> </span><span class="org-constant">:eyes</span>,<span class="org-whitespace-space"> </span><span class="org-constant">:look</span>
<span class="org-whitespace-space">  </span>def_delegator<span class="org-whitespace-space"> </span><span class="org-constant">:ears</span>,<span class="org-whitespace-space"> </span><span class="org-constant">:lisen</span>
<span class="org-whitespace-space">  </span>def_delegator<span class="org-whitespace-space"> </span><span class="org-constant">:nose</span>,<span class="org-whitespace-space"> </span><span class="org-constant">:smell</span>
<span class="org-keyword">end</span>
</pre>
<p> A potion of infravision might then replace the character&#8217;s eyes with infrared-enhanced ones: </p>
<pre class="src src-ruby"><span class="org-keyword">class</span><span class="org-whitespace-space"> </span><span class="org-type">InfravisionPotionDecorator</span><span class="org-whitespace-space"> </span>&lt;<span class="org-whitespace-space"> </span><span class="org-type">SimpleDelegator</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">class</span><span class="org-whitespace-space"> </span><span class="org-type">EyesDecorator</span><span class="org-whitespace-space"> </span>&lt;<span class="org-whitespace-space"> </span><span class="org-type">SimpleDelegator</span>
<span class="org-whitespace-space">    </span><span class="org-comment-delimiter">#</span><span class="org-whitespace-space"> </span><span class="org-comment">...</span>
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>

<span class="org-whitespace-space">  </span><span class="org-keyword">def</span><span class="org-whitespace-space"> </span><span class="org-function-name">initialize</span>(character)
<span class="org-whitespace-space">    </span><span class="org-keyword">super</span>(character)
<span class="org-whitespace-space">    </span>character.eyes<span class="org-whitespace-space"> </span>=<span class="org-whitespace-space"> </span><span class="org-type">EyesDecorator</span>.new(character.eyes)
<span class="org-whitespace-space">  </span><span class="org-keyword">end</span>
<span class="org-keyword">end</span>
</pre>
<p> &hellip;but this is an awful lot of code and ceremony. It might make sense someday, but right now it feels like massive overkill. The module extension approach, by contrast, is only a small change from our original version. </p>
</p></div>
</p></div>
<div id="outline-container-6" class="outline-3">
<h3 id="sec-6">Are decorators overrated?</h3>
<div class="outline-text-3" id="text-6">
<p> So what can we learn from this? When composing objects, Is it always better to use module extension than decoration? </p>
<p> In a word, no. For one thing, decoration is a simpler structure to understand. Given object <code>A</code> wrapped in object <code>B</code> wrapped in object <code>C</code>, it&#8217;s easy to reason about how method calls will be handled. They&#8217;ll always go one-way: a method in object <code>A</code> will never reference a method in <code>B</code> or <code>C</code>.By contrast, method calls in a module-extended object can bounce around the inheritance heirarchy in unexpected ways. </p>
<p> A second consideration is that once you&#8217;ve extended an object with a module, its behavior is changed for <strong>all</strong> clients, including itself. You can&#8217;t interact with the &#8220;unadorned&#8221; object anymore. You might extend an object for your own purposes, then pass it to a third-party method which doesn&#8217;t understand the modified behavior of the object and barfs as a result. </p>
<p> Finally, there&#8217;s a performance penalty. While it varies from implementation to implementation, dynamically extending objects can slow down your code as a result of the method cache beign invalidated. Of course, as with all performance-related guidelines, be sure to profile before making any code changes based on this point. </p>
</p></div>
</p></div>
<div id="outline-container-7" class="outline-3">
<h3 id="sec-7">Conclusion</h3>
<div class="outline-text-3" id="text-7">
<p> Decoration and module extension are both viable ways to compose objects in Ruby. Which to use is not a simple black-or-white choice; it depends on the purpose of the composition.  </p>
<p> For applications where you want to adorn an object with some extra functionality, or modify how it presents itself, a decorator is probably the best bet. Decorators are great for creating Presenters, where we just want to change an object&#8217;s &#8220;face&#8221; in a specific context.  </p>
<p> On the other hand, when building up a composite object at runtime object out of individual &#8220;aspects&#8221; or &#8220;facets&#8221;, module extension may make more sense. Judicious use of module extension can lead to a kind of &#8220;emergent behavior&#8221; which is hard to replicate with decoration or delegation. </p>
<p> At least, this has been my experience. Got some experiences or opinions on decoration vs. module extension? Feel free to leave a note in the comments! </p>
</div></div>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2012/01/31/decoration-is-best-except-when-it-isnt/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>SBPP #4: method Cascades</title>
		<link>http://devblog.avdi.org/2011/09/26/sbpp-4-method-cascades/</link>
		<comments>http://devblog.avdi.org/2011/09/26/sbpp-4-method-cascades/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 13:00:41 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Smalltalk Best Practice Patterns]]></category>
		<category><![CDATA[combinators]]></category>
		<category><![CDATA[kestrel]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1723</guid>
		<description><![CDATA[In Smalltalk, you can &#8220;cascade&#8221; side-effectful calls to the same object using the semicolon (;) operator. E.g.: If I understand it correctly, the semicolon is effectively a K-combinator or &#8220;Kestrel&#8221;. I am jealous. Sure, we have Object#tap, but that&#8217;s awfully &#8230; <a href="http://devblog.avdi.org/2011/09/26/sbpp-4-method-cascades/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>In Smalltalk, you can &#8220;cascade&#8221; side-effectful calls to the same object using the semicolon (;) operator. E.g.:</p>
<script src="https://gist.github.com/1238072.js"></script><noscript><pre><code class="language-smalltalk smalltalk">aStream
    print: x;
    nextPutOn: ' @ ';
    print: y
</code></pre></noscript>
<p>If I understand it correctly, the semicolon is effectively a <a href="https://github.com/raganwald/homoiconic/blob/master/2008-10-29/kestrel.markdown#readme">K-combinator or &#8220;Kestrel&#8221;</a>.</p>
<p>I am jealous. Sure, we have Object#tap, but that&#8217;s awfully verbose by comparison:</p>
<script src="https://gist.github.com/1238083.js"></script><noscript><pre><code class="language-ruby ruby">$stdout.tap do |s| 
  s.print x     end.tap do |s| 
  s.print ' @ ' end.tap do |s| 
  s.print y
end
</code></pre></noscript>
<p>(I&#8217;m using multiple taps in order to exactly mimic the semantics of the Smalltalk semicolon operator in the example above.)</p>
<p>Let&#8217;s see if we can do better for this simple case of cascading a series of commands, while ignoring their return values.</p>
<script src="https://gist.github.com/1238090.js"></script><noscript><pre><code class="language-ruby ruby">module Cascadable
  class CascadeProxy &lt; BasicObject
    def initialize(object)
      @object = object
    end

    def method_missing(*args, &amp;block)
      @object.send(*args, &amp;block)
      return self
    end
  end

  def cascade
    return CascadeProxy.new(self)
  end
  alias_method :k, :cascade
end

class Object
  include Cascadable
end

$stdout.k.
  print(x).
  print(' @ ').
  print(y)
</code></pre></noscript>
<p>Yay! That looks a lot nicer.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/09/26/sbpp-4-method-cascades/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>SBPP #3: Reversing Method</title>
		<link>http://devblog.avdi.org/2011/09/23/sbpp-3-reversing-method/</link>
		<comments>http://devblog.avdi.org/2011/09/23/sbpp-3-reversing-method/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 13:00:55 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Smalltalk Best Practice Patterns]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1714</guid>
		<description><![CDATA[I&#8217;m pleased to find Kent Beck shares my affinity for methods with a consistent cadence. In the next pattern I translate, he looks for a way to bring a uniform rhythm to a method that writes an object to a &#8230; <a href="http://devblog.avdi.org/2011/09/23/sbpp-3-reversing-method/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m pleased to find Kent Beck shares my affinity for methods with a consistent cadence. In the next pattern I translate, he looks for a way to bring a uniform rhythm to a method that writes an object to a stream.</p>
<script src="https://gist.github.com/1236930.js"></script><noscript><pre><code class="language-ruby ruby"># Reversing Method

# There is an easy solution for the specific case of writing to an
# output stream. I'll put that at the end. First, I'll translate
# literally into Ruby.

# Example 1
class Point
  attr_accessor :x, :y

  def initialize(x, y)
    @x, @y = x, y
  end

  def print_on(stream)
    x.print_on(stream)
    stream.next_put_all(' @ ')
    y.print_on(stream)
  end
end

# Example 2
class Stream
  def print(object)
    object.print_on(self)
  end
end

class Point
  def print_on(stream)
    stream.print x
    stream.next_put_all ' @ '
    stream.print y
  end
end

# Of course, Ruby has no such thing as &quot;Stream&quot;. It has a conventional
# notion of an 'IO-like' object, but no unifying module along the
# lines of Enumerable or Comparable which is included by all IO-like
# objects. More's the pity.

# We could put this functionality in a module, and include it into
# IO-likes as needed. We'll call it #print_obj since #print is already
# taken by IO-likes.

module ObjectPrinter
  def print_obj(object)
    object.print_on(self)
  end
end

class Point
  def print_on(io)
    io.print x
    io.print ' @ '
    io.print y
  end
end

$stdout.extend(ObjectPrinter)
p = Point.new(23,32)
p.print_on($stdout)
 

# However, for the specific case of handling output, Ruby has a
# solution which is concise and functionally equivalent to the
# Smalltalk example:

class Point
  def print_on(io)
    io &lt;&lt; x &lt;&lt; ' @ ' &lt;&lt; y
  end
end

puts # blank line
p.print_on($stdout)
  
</code></pre></noscript>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/09/23/sbpp-3-reversing-method/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SBPP #2: Smalltalk Patterns in Ruby</title>
		<link>http://devblog.avdi.org/2011/09/22/sbpp-2-smalltalk-patterns-in-ruby/</link>
		<comments>http://devblog.avdi.org/2011/09/22/sbpp-2-smalltalk-patterns-in-ruby/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 15:35:14 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Smalltalk Best Practice Patterns]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1696</guid>
		<description><![CDATA[Smalltalk Best Practice Patterns continues from the introduction with a brief explanation of patterns. Some notable quotes: About leveraging commonality: &#8220;large-scale software re-use has not proven to be the answer&#8221;. A lot of the mid-90s OO PR centered around the &#8230; <a href="http://devblog.avdi.org/2011/09/22/sbpp-2-smalltalk-patterns-in-ruby/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X%3FSubscriptionId%3DAKIAIRXKO4LLU2ACVMRQ%26tag%3Dthlafa-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D013476904X">Smalltalk Best Practice Patterns</a> continues from the introduction with a brief explanation of patterns. Some notable quotes:</p>
<ul>
<li>About leveraging commonality: &#8220;large-scale software re-use has not proven to be the answer&#8221;. A lot of the mid-90s OO PR centered around the idea that we&#8217;d all build our apps out of reusable off-the-shelf objects. As Beck notes, this didn&#8217;t really pan out. With rare exceptions, in-process software re-use still takes the form it always did: it happens at the &#8220;library&#8221; level of granularity, not at the object level. Patterns have been a much more successful way to re-use ideas.</li>
<li>&#8220;By carrying along their justification, patterns avoid the problem of most &#8220;style guides&#8221; that simply prescribe solutions without discussing why or when the solution is appropriate&#8221;.  Ironically, I often hear the criticism that patterns are &#8220;prescriptive, one-size-fits-all solutions&#8221;. When I hear this it makes me wonder if the person saying it has read a patterns book lately. Central to the form is a careful discussion of when the pattern makes sense, and when it doesn&#8217;t.</li>
</ul>
<p>Once I got into the meat of the book I decided that, since I&#8217;m reading it for the <a href="http://rubyrogues.com/">Ruby Rogues</a> book club, I should probably take a stab at translating the patterns to Ruby. You are welcome to follow my progress on GitHub:  <a href="https://github.com/avdi/sbpprb">https://github.com/avdi/sbpprb</a>. Also, feel free to fork and submit pull requests for alternate translations. There is definitely room for interpretation on some of these.</p>
<ul>
<li>On <strong>Composed Method,</strong> this bit is key: &#8221;keep all operations in a method at the same level of abstraction&#8221;. I hate it when I find a system that has been broken up into small methods&#8212;except that the small methods still combine high-level calls with fiddly, low-level code. Code like this has all the disadvantages of small methods (harder to follow the logic) with none of the advantages (only having to introduce a change in one place).</li>
<li>There are a number of construction &amp; coercion patterns early in the book. One thought that sprung out to me in reading these is that I don&#8217;t spend enough time thinking about writing alternatives to &#8220;.new&#8221; in Ruby code. More often, I just write a fancy &#8220;#initialize&#8221; which can handle various combinations of arguments. But there&#8217;s a good argument to be made in many classes for avoiding .new and instead defining more specific forms, e.g. Point.new_from_coords, Point.new_from_polar.</li>
<li>That last point is relevant to Rails code. A lot of the specialized factory methods I see for testing (&#8220;Factory.create(:admin_user)&#8221;) really ought to have analogs on the original model (User.new_admin).</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/09/22/sbpp-2-smalltalk-patterns-in-ruby/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>SBPP #1: Introduction</title>
		<link>http://devblog.avdi.org/2011/09/20/sbpp-1-introduction/</link>
		<comments>http://devblog.avdi.org/2011/09/20/sbpp-1-introduction/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 13:00:11 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Smalltalk Best Practice Patterns]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1693</guid>
		<description><![CDATA[The Ruby Rogues are reading Smalltalk Best Practice Patterns for next month&#8217;s book club, so I finally got around to ordering a copy. It&#8217;s high time, considering that in my experience it&#8217;s one of the most consistently recommended programming books &#8230; <a href="http://devblog.avdi.org/2011/09/20/sbpp-1-introduction/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>The <a href="http://rubyrogues.com/">Ruby Rogues</a> are reading <a href="http://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X%3FSubscriptionId%3DAKIAIRXKO4LLU2ACVMRQ%26tag%3Dthlafa-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D013476904X">Smalltalk Best Practice Patterns</a> for next month&#8217;s book club, so I finally got around to ordering a copy. It&#8217;s high time, considering that in my experience it&#8217;s one of the most consistently recommended programming books in print.</p>
<p>Some notes and quotes from the introduction:</p>
<ul>
<li>Defining patterns: &#8220;a pattern is a decision an expert makes over and over&#8221;.</li>
<li>Patterns in the small: &#8220;I&#8217;m constantly amazed at how even a little help cleaning up small problems reveals the source and solution of much bigger problems&#8221;.</li>
<li>&#8220;It is easy to get numbed to pain and frustration, or treat it as if is part of the territory&#8221;&#8212;this dovetails with a realization I had recently: my &#8220;Confident Code&#8221; talk, at its core, isn&#8217;t about clean code; it&#8217;s about <em>joy</em>. Programming in a conducive programming language should be pleasant. Fun. Joyful, even. Antipatterns steal joy because they add weight to every step. It&#8217;s worthwhile to periodically remember the joy of that first &#8220;a-ha!&#8221; moment in Ruby (or Smalltalk, or whatever), and figure out if and why we aren&#8217;t feeling that way anymore.</li>
<li>&#8220;The very act of deciding what corners to cut slows down development. Using these patterns lets you program flat out, applying patterns as fast as your fingers will go, and get results as quickly as possible&#8221;. Beck goes on to say of adopting these patterns &#8220;whole hog&#8221;: &#8220;&#8230;I spent a couple of frustrating weeks programming at less than full speed. After that, I memorized enough patterns to get back up to my old productivity, but the code I was producing was cleaner than before. After a couple more weeks, I no longer had to look up any patterns, and my productivity shot up while my code kept getting cleaner and cleaner.&#8221;</li>
</ul>
<p>This last quote nicely sums up an observation I&#8217;ve made over the years. A lot of programmers, when evaluating a new discipline, note (correctly) that adopting it will slow them down in the short term. They then extrapolate from this short-term slowdown that it will <em>always </em>slow them down, and is therefore a waste of time.</p>
<p>Maybe it&#8217;s just good &#8216;ole hacker hubris: the assumption that we can fully assimilate any new knowledge in a matter of hours, and if not, it&#8217;s not worth learning. In any case, it&#8217;s a flawed mental model. New disciplines, when practiced diligently, eventually become automatic.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/09/20/sbpp-1-introduction/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Your Code is My Hell</title>
		<link>http://devblog.avdi.org/2011/08/22/your-code-is-my-hell/</link>
		<comments>http://devblog.avdi.org/2011/08/22/your-code-is-my-hell/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 13:30:26 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Rants]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[legacy]]></category>
		<category><![CDATA[maintenance]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[ruby. rails]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1453</guid>
		<description><![CDATA[It occurred to me recently that my experience as a Rails developer may be somewhat unique. I often get brought in to help preexisting Ruby/Rails projects evolve and mature in a sustainable way. As a result, the vast majority of &#8230; <a href="http://devblog.avdi.org/2011/08/22/your-code-is-my-hell/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>It occurred to me recently that my experience as a Rails developer may be somewhat unique.</p>
<p>I often get brought in to help preexisting Ruby/Rails projects evolve and mature in a sustainable way. As a result, the vast majority of Ruby projects I&#8217;ve worked on have been well-established by the time I arrived. In fact, offhand I can only think of <em>one</em> commercial greenfield Ruby project I&#8217;ve participated in. All the rest have been &#8220;legacy&#8221; from my perspective, in the sense that there was a sizable codebase in production before I showed up. (I&#8217;m not counting personal and internal projects.)</p>
<p>I&#8217;ve realized that in this my experience may be somewhat unusual among Ruby and Rails developers. With its fast churn and startup-heavy community, a lot of Rubyists are working on projects that they started recently.  My work is more in the codebases where the original programmers have moved on.</p>
<h3>Rails&#8217; dirty secret</h3>
<p>In the days before I got paid to write Ruby, I worked on some legacy codebases that had histories spanning multiple decades and 100s of KLOCs. That&#8217;s a lot of opportunity for bad code to accumulate; and in some cases, the accumulations were impressive.</p>
<p>But here&#8217;s the dirty little secret of Rails development:<strong> the messiest, nastiest big-ball-of-mud code I have seen in my entire career has been in Ruby on Rails projects</strong>. I&#8217;ve seen Rails projects that accumulated enough <a href="http://avdi.org/devblog/2011/08/15/the-coding-wasteland/">technical debt and waste</a> in two years to make 10 year-old C/C++ programs look clean and elegant by comparison. And it wasn&#8217;t just one project. I&#8217;ve seen it over and over.</p>
<p>In a way I think this is a testament to the power of the platform. If you&#8217;re getting a 500 error in a Rails app, you can keep adding kludge after kludge and hitting &#8220;reload&#8221; until it works. No need to ever write a test or refactor. In languages and frameworks with a slower turnaround time, this kind of tweak-it-till-it-works workflow is simply impractical. Ruby on Rails has an impressively low barrier to fiddling.</p>
<p>Unfortunately, as a result a lot of projects I come to on have hit what I think of as the <em>productivity crash</em>. At some point the cumulative effect of all those little shortcuts catches up with the development team, and changes that would once have taken a day start taking two weeks as all the dependencies and unintended consequences are sorted out.</p>
<p>As a somewhat ranty aside: this is also the point where, often, original members of the team start moving on to bigger and better things. Meanwhile the crew that inherited the codebase is left to field questions from management about why they can&#8217;t seem to push out changes nearly as fast as the old team. The new team is confronted with the problem of getting the codebase under better test coverage and a little more modularized before they can ramp velocity back up; thus perpetuating the notion among the business types that testing and refactoring just slows things down. And/or that the original team were some kind of wizards.</p>
<p>Okay, rant over.</p>
<h3>But Rails is different!</h3>
<p>Rails developers are sometimes accused of being arrogant and judgmental. I&#8217;m not sure how true this is; I don&#8217;t see it all that much, but maybe I&#8217;m too close to the community and/or arrogant and judgemental myself to be a fair observer.</p>
<p>What I <em>do</em> see is a kind of &#8220;Rails exceptionalism&#8221;.  Remember back in the first dot-com boom, when some economists were saying that no, this time it was <em>different</em>, the Internet had changed the game this time the markets would just keep going up and up? The phenomenon I see is similar in spirit. it&#8217;s a belief, perhaps not fully conscious, that Ruby on Rails development is somehow <em>different</em>, and not subject to the forces affecting other software projects.</p>
<p>Here are a few examples, just to give you an idea of what I&#8217;m talking about:</p>
<ul>
<li>&#8220;Design Patterns are a Java thing. In Ruby you just write code.&#8221;</li>
<li>&#8220;The warnings Ruby produces are dumb; just disable them.&#8221;</li>
<li>&#8220;Sure they aren&#8217;t technically Unit Tests, but isolating objects turned out to be kind of hard and besides nobody else is doing it.&#8221;</li>
<li>&#8220;Monkeypatching is frowned on in other languages, but in Ruby it&#8217;s fine. The downsides almost never materialize.&#8221;</li>
<li>&#8220;Stuff like the <a href="http://avdi.org/devblog/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/">Law of Demeter</a> isn&#8217;t really as important in Ruby code&#8221;</li>
<li>&#8220;Dividing methods into private and public is for control freaks, you don&#8217;t need it in Ruby&#8221;</li>
<li>&#8220;That&#8217;s only a code smell when it&#8217;s in Java code&#8221;</li>
<li>&#8220;That&#8217;s only a problem in large projects&#8221; (implying that this project will never become large).</li>
</ul>
<p>I also see a fair amount of project or subsystem-level exceptionalism: &#8220;I know they say classes shouldn&#8217;t be this big, but for this class it just makes sense for all of that stuff to be in one place&#8221;.</p>
<h3>Welcome to Lilliput</h3>
<p>The truth is, Ruby on Rails projects <em>are</em> exceptional in a way: <strong>they are really small</strong>. In James Gray&#8217;s terrific keynote at <a href="http://lonestarrubyconf.com/">Lone Star Ruby Conf</a> this past week, he mentioned &#8220;huge projects&#8221; of 40+ KLOC. That gave me a smile, because the first two Rails projects I was ever paid to work on were 50KLOC and 70KLOC, respectively. And while that may seem like a lot of code, that&#8217;s <em>small</em> by industry standards.</p>
<p>There are a few reasons for this. Ruby <em>is</em> a more expressive language than, say, Java, so to some degree Rails projects will always be smaller than equivalent projects in higher-ceremony languages.</p>
<p>It&#8217;s also possible that Rails programmers have embraced the wisdom of breaking systems many, small, intercommunicating apps. I&#8217;d like to believe this, but experience suggests this strategy has seen only spotty uptake.</p>
<p>No, I think the biggest reason for the diminutive nature of Rails apps is also the most obvious: they are all pretty young. It&#8217;s a young framework, and there&#8217;s a lot of churn in this community. A Rails app that lasts three years is ancient.</p>
<p>I think it&#8217;s safe to say that this situation won&#8217;t last. We&#8217;re going to see larger and larger codebases. And here&#8217;s a not-very-daring prediction: a lot of projects are going to hit the very same architectural roadblocks that Lisp, Smalltalk, Pascal, C++, and Java projects hit before them.</p>
<h3>You are not a special snowflake</h3>
<p>It&#8217;s funny reading<a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.84.6924&amp;rep=rep1&amp;type=pdf"> programming literature from the 80s</a>. Dynamic, object-oriented systems navigating the transition from &#8220;small&#8221; to &#8220;medium-sized&#8221;. Sound familiar?</p>
<p>Every revolutionary believes <em>his</em> revolution is special, and won&#8217;t devolve into the partisan bickering and venal bureaucracy that the <em>last</em> revolution led to. And it&#8217;s easy to believe at first. Everyone&#8217;s excited and eager to help; the problems are relatively small; and the marketing drones haven&#8217;t latched onto the movement yet.</p>
<p>The truth is, the problem you are solving probably isn&#8217;t as special as you think it is. And those <a href="http://nicksda.apotomo.de/2011/08/rails-misapprehensions-the-dependency-injection-pattern/">byzantine patterns</a> you thought were a relic of a bygone age were invented by people using <a href="http://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X%3FSubscriptionId%3DAKIAIRXKO4LLU2ACVMRQ%26tag%3Dthlafa-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D013476904X">languages surprisingly similar to Ruby</a>.</p>
<h3>Don&#8217;t panic</h3>
<p>Relax. I&#8217;m not here to tell you that the last few years were all just a lovely dream, and you&#8217;re really still strapped to a chair in the Ministry of UML.</p>
<p>Ruby is still a wonderful language, and the terrific thing about it is that it adapts to large-system design patterns remarkably easily, and with very little ceremony. Dependency Injection? It&#8217;s a one-liner. Object delegation and composition? Piece of cake. Contrary to misconceptions, Ruby doesn&#8217;t obviate solid design patterns and SOLID principles; what it does is make them very easy to express. In fact, the ease of expressing robust architectural styles was what attracted some of us early-adopters to the language in the first place.</p>
<p>Just please, do me a favor: before you tell me that Ruby and Rails doesn&#8217;t need any of this discipline, have a chat with the guy or gal who is still maintaining the <em>first</em> Rails app you worked on.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/08/22/your-code-is-my-hell/feed/</wfw:commentRss>
		<slash:comments>125</slash:comments>
		</item>
		<item>
		<title>Fowler on Rails</title>
		<link>http://devblog.avdi.org/2011/07/27/fowler-on-rails/</link>
		<comments>http://devblog.avdi.org/2011/07/27/fowler-on-rails/#comments</comments>
		<pubDate>Wed, 27 Jul 2011 18:35:17 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[datamapper]]></category>
		<category><![CDATA[Martin Fowler]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[templates]]></category>
		<category><![CDATA[two step view]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1490</guid>
		<description><![CDATA[Projects using Ruby on Rails often lack strong distinctions in two main areas: The model/record conflation: Seeing &#8220;models&#8221; as strictly DB-backed resources. The view/template conflation: failing to draw a line between view objects and HTML templates. The conflations are encouraged &#8230; <a href="http://devblog.avdi.org/2011/07/27/fowler-on-rails/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><img class="alignright" src="http://ecx.images-amazon.com/images/I/511D6FdsbXL._SL160_.jpg" alt="" width="128" height="160" /></p>
<p>Projects using Ruby on Rails often lack strong distinctions in two main areas:</p>
<ul>
<li>The model/record conflation: Seeing &#8220;models&#8221; as strictly DB-backed resources.</li>
<li>The view/template conflation: failing to draw a line between view objects and HTML templates.</li>
</ul>
<p>The conflations are encouraged by Rails&#8217; design decisions. When choosing which enterprise design patterns to translate into code, the Rails developers chose <a href="http://martinfowler.com/eaaCatalog/activeRecord.html">Active Record</a> (a relatively thin, one-to-one take on the ORM idea), and <a href="http://martinfowler.com/eaaCatalog/templateView.html">Template View</a>.</p>
<p>I am not faulting them for this decision. These were both thoroughly pragmatic decisions which mapped well to the kind of applications that Rails was aimed at. By encoding these opinions into the framework and covering them with a sweet coating of convention-over-configuration, Rails saved thousands of projects from pattern analysis paralysis.</p>
<p>But now Rails applications are maturing, and a lot of developers are starting to realize that these patterns may not scale so well to more and more complex applications.  When figuring out how to move forward, we could do much worse than to consult the same book that laid the blueprints for Rails&#8217; architecture, <a title="Patterns of Enterprise Application Architecture (Amazon affiliate link)" href="http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420%3FSubscriptionId%3DAKIAIRXKO4LLU2ACVMRQ%26tag%3Dthlafa-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0321127420">Patterns of Enterprise Application Architecture</a>.</p>
<p>Here&#8217;s Martin Fowler on <a href="http://martinfowler.com/eaaCatalog/domainModel.html">Domain Models</a>:</p>
<blockquote><p>An OO domain model will often look similar to a database model, yet it will still have a lot of differences. A <em>Domain Model</em> mingles data and process, has multivalued attributes and a complex web of associations, and uses inheritance.</p>
<p>As a result I see two styles of <em>Domain Model</em> in the field. A simple <em>Domain Model</em> looks very much like the database design with mostly one domain object for each database table. A rich <em>Domain Model</em> can look different from the database design, with inheritance, strategies, and other [Gang of Four] patterns, and complex webs of interconnected objects. A rich <em>Domain Model</em> is better for more complex logic, but is harder to map to the database. A simple <em>Domain Model</em> can use <em>Active Record</em>, whereas a rich <em>Domain Model </em>requires <em><a href="http://martinfowler.com/eaaCatalog/dataMapper.html">Data Mapper</a>.</em></p></blockquote>
<p>Note that Fowler is referring to the Active Record and Data Mapper design patterns, not to the Ruby libraries those patterns inspired. There is a correspondence, though: the <a href="http://datamapper.org/">DataMapper</a> library, like the pattern it is based on, puts a higher value on decoupling the domain model from the database schema.</p>
<p>Now on to views. Here&#8217;s Fowler talking about <em><a href="http://martinfowler.com/eaaCatalog/twoStepView.html">Two Step Views</a></em>, an alternative to the <em>Template View</em> pattern:</p>
<blockquote><p>You may&#8230; want to want to make global changes to the appearance of the site easily, but common approaches using <em>Template View</em> or <em>Transform View</em> make this difficult because presentation decisions are often duplicated across multiple pages or transform modules. A global change can force you to change several files.</p>
<p><em>Two Step View</em> deals with this problem by splitting the transformation into two stages. The first transforms the model data into a logical presentation without any special formatting; the second converts that logical presentation with the actual formatting needed.</p></blockquote>
<p>I do a lot of two-step view processing in my projects. I haven&#8217;t had a chance to take a close look at, but I think this process is also what Jeff Casimir is aiming at with <a href="https://github.com/jcasimir/draper">Draper</a>, and I support and applaud his efforts.</p>
<p>And that&#8217;s all I had to say about that&#8230; I just wanted to post those quotes in case anyone else found them noteworthy.</p>
<div class="zemanta-pixie" style="margin-top: 10px; height: 15px;"><a class="zemanta-pixie-a" title="Enhanced by Zemanta" href="http://www.zemanta.com/"><img class="zemanta-pixie-img" style="border: none; float: right;" src="http://img.zemanta.com/zemified_e.png?x-id=460ae14f-a0a9-4b56-b0c2-31f41094dfa9" alt="Enhanced by Zemanta" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/07/27/fowler-on-rails/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>
