<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Dynamic and Concise &#187; DRY</title>
	<atom:link href="http://yiwenandsoftware.wordpress.com/tag/dry/feed/" rel="self" type="application/rss+xml" />
	<link>http://yiwenandsoftware.wordpress.com</link>
	<description>Everything about my experience with Software Development</description>
	<lastBuildDate>Sat, 14 Mar 2009 22:05:25 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='yiwenandsoftware.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/fa9ad49ca1c5d02890788e46a95fe979?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Dynamic and Concise &#187; DRY</title>
		<link>http://yiwenandsoftware.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://yiwenandsoftware.wordpress.com/osd.xml" title="Dynamic and Concise" />
		<item>
		<title>List Presenter</title>
		<link>http://yiwenandsoftware.wordpress.com/2008/10/28/list-presenter/</link>
		<comments>http://yiwenandsoftware.wordpress.com/2008/10/28/list-presenter/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 04:07:42 +0000</pubDate>
		<dc:creator>Yi Wen</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[DRY]]></category>

		<guid isPermaLink="false">http://yiwenandsoftware.wordpress.com/?p=43</guid>
		<description><![CDATA[In a typical Rails app, we have a lot of &#8220;index&#8221; action in almost every controllers. And in most cases, an index is a list of same type of objects. There are a lot of similar features we need to present these lists. So it makes sense to have a concept as ListPresenter and each [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=yiwenandsoftware.wordpress.com&blog=2109631&post=43&subd=yiwenandsoftware&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In a typical Rails app, we have a lot of &#8220;index&#8221; action in almost every controllers. And in most cases, an index is a list of same type of objects. There are a lot of similar features we need to present these lists. So it makes sense to have a concept as ListPresenter and each individual presenter who presents a list should extend from it.</p>
<p>Of course, in Ruby, we don&#8217;t have to actually have a class called ListPresenter and do all the stuff that are not necessarily related to each other. We can have as many modules as we need. Each module does one particular task. and all presenters for list can mixin those modules.</p>
<p>Why it is good to do things this way? Let&#8217;s take an example: If all lists are HTML tables, and all tables have table headers with title of columns. Now we decide to use title case (such as &#8216;Column Name&#8217;) for these headers, we could manually type in these texts into your HTML template. The approach is straightforward, but bearing three potential problems. </p>
<ol>
<li>Since developers generally do not know how to type, one could easily have typos
<li>Two developers may develop two lists and one may think, wrongly, that title should be humanized (such as &#8220;Column name&#8221;). Then we end up with inconsistent UI. This inconsistency could also happen when a developer produced lists before the team decided title case. So he used humanized words back then. He had to come back fix them one by one, even with the best IDE ever &#8211; Windows notepad&#8217;s help, it still a tedious and boring task.
<li>Later on, the business doesn&#8217;t like title case, they want humanized case. Well, 4 boring hours, again!
</ol>
<p>In this case, a simple method can help, all it takes is a module which provides a html_table_columns method, as the following:</p>
<pre class="brush: ruby;">
module HtmlTableColumns
  def html_table_columns(*args)
    self.send :define_method, :columns do
      returning([]) do |columns_hash|
        args.each do |arg|
          case arg
            when String, Symbol
              columns_hash &lt;&lt; arg.to_s.titlecase})
            when Hash
              columns_hash &lt;&lt; HashWithIndifferentAccess.new(arg)
            else
              raise ArgumentError.new(&quot;The params must be Hash, String or Symbols&quot;)
          end
        end
      end
    end
  end
end
</pre>
<p>This method defines a <i>columns</i> for class who calls this method. A call like:</p>
<pre class="brush: ruby;">
  table_columns('name', &quot;last_connected&quot;
  {'user_login' =&gt; &quot;User&quot;}, 'status')
</pre>
<p>will generate a method like this (in RSpec):</p>
<pre class="brush: ruby;">
      presenter.columns.should ==
      [{'name' =&gt; 'Name'},
       {&quot;last_connected&quot;=&gt;&quot;Last Connected&quot;},
        {'user_login' =&gt; &quot;User&quot;}, {'status' =&gt; &quot;Status&quot;}]
</pre>
<p>As long as every developer uses this method, there will be no typo, no inconsistency. And if people ever want to change from title case to humanized words, there is only one place that needs to be changed and I believe readers know where.</p>
<p>This is just an example how group similar features into one place is nice. In general I believe if I can find a feature that is across more than one places, it&#8217;s worth my effort to group them into one place, use whatever pattern that is applicable. So after all, I guess this post is not about List Presenter, it is about a case study of DRY.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/yiwenandsoftware.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/yiwenandsoftware.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/yiwenandsoftware.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/yiwenandsoftware.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/yiwenandsoftware.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/yiwenandsoftware.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/yiwenandsoftware.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/yiwenandsoftware.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/yiwenandsoftware.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/yiwenandsoftware.wordpress.com/43/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=yiwenandsoftware.wordpress.com&blog=2109631&post=43&subd=yiwenandsoftware&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://yiwenandsoftware.wordpress.com/2008/10/28/list-presenter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f711c24e96cbc441b0c94141f22f2d23?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">hayafirst</media:title>
		</media:content>
	</item>
	</channel>
</rss>