<?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>Tea-Driven Development &#187; design</title>
	<atom:link href="http://blog.mattwynne.net/tag/design/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mattwynne.net</link>
	<description>Matt Wynne taking it one tea at a time</description>
	<lastBuildDate>Tue, 10 Jan 2012 20:07:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>The Fable of the User-Centred Designer</title>
		<link>http://blog.mattwynne.net/2010/08/30/the-fable-of-the-user-centred-designer/</link>
		<comments>http://blog.mattwynne.net/2010/08/30/the-fable-of-the-user-centred-designer/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 10:50:18 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Agile / Lean Software Development]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[UCD]]></category>

		<guid isPermaLink="false">http://blog.mattwynne.net/2010/08/30/the-fable-of-the-user-centred-designer/</guid>
		<description><![CDATA[Agile software development is not really about burn-down-charts, unit tests, refactoring or code metrics or even pair programming. At it&#8217;s heart, it&#8217;s about building software that really works for the people who are going to use it. All those practices you read about are just tools that help you to develop software iteratively, so that [...]]]></description>
			<content:encoded><![CDATA[<p>Agile software development is not really about burn-down-charts, unit tests, refactoring or code metrics or even pair programming. At it&#8217;s heart, it&#8217;s about building software that really works for the people who are going to use it. All those practices you read about are just tools that help you to develop software iteratively, so that you can keep moving the software closer and closer to becoming what it&#8217;s users actually want.</p>

<p>The goal is not the practices themselves, but the ability they give you to iterate.</p>

<p>If you really want to build software iteratively, you also need to understand about User-Centric Design. I&#8217;m finally getting the opportunity to get involved with a project early enough to put this into practice myself. Here&#8217;s a <a href="http://www.userfocus.co.uk/pdf/fable.pdf">great introduction I just found</a>.</p>

<p>In summary:</p>

<ul>
<li>Early and continual focus on user and their tasks</li>
<li>Empirical measurement of user behaviour</li>
<li>Iterative design</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattwynne.net/2010/08/30/the-fable-of-the-user-centred-designer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails Tip: Use Polymorphism to Extend your Controllers at Runtime</title>
		<link>http://blog.mattwynne.net/2009/07/11/rails-tip-use-polymorphism-to-extend-your-controllers-at-runtime/</link>
		<comments>http://blog.mattwynne.net/2009/07/11/rails-tip-use-polymorphism-to-extend-your-controllers-at-runtime/#comments</comments>
		<pubDate>Sat, 11 Jul 2009 20:35:04 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Ruby Programming]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[Polymorphism]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.mattwynne.net/2009/07/11/rails-tip-use-polymorphism-to-extend-your-controllers-at-runtime/</guid>
		<description><![CDATA[Metaprogramming in Ruby comes in for quite a bit of stick at times, the accusation being that code which modifies itself at runtime can be hard to understand. As Martin Fowler recently described, there&#8217;s a sweet spot where you use just enough to get some of the incredible benefits that Ruby offers, without leaving behind [...]]]></description>
			<content:encoded><![CDATA[<p>Metaprogramming in Ruby comes in for quite a bit of stick at times, the accusation being that code which modifies itself at runtime can be hard to understand. As <a href="http://martinfowler.com/articles/rubyAtThoughtWorks.html#IsARubyCode-baseHardToUnderstand">Martin Fowler recently described</a>, there&#8217;s a sweet spot where you use just enough to get some of the incredible benefits that Ruby offers, without leaving behind a minefield for future developers who&#8217;ll have to maintain your code.</p>

<p>One of my favourite techniques uses the <a href="http://ruby-doc.org/core/classes/Object.html#M000335">Object#extend</a> method, which allows you to mix in the methods from a module to a specific instance of a class at run-time. In my quest to <a href="http://www.antiifcampaign.com/">eliminate as much conditional logic as possible</a> from my code, I&#8217;ve seen a common pattern emerge a few times. Here&#8217;s an example from a refactoring session I paired on with my colleague <a href="http://craig-mackenzie.com/">craig</a>.</p>

<p>We start with a Rails controller which handles user authentication. Over the passing iterations, it has grown to support not only bog-standard logins from users of the main web application, but a form that&#8217;s displayed on a 3rd-party partner site, as well as during the installation of a rich-client GUI app. All these clients need slightly different behaviour &#8211; different templates or layout to be rendered, and different destination pages to redirect to when the login has succeded.</p>

<p>Sadly the hackers passing through this controller have not been great <a href="http://www.informit.com/articles/article.aspx?p=1235624&amp;seqNum=6">boy scouts</a>, and the code has started to get pretty unpleasant. This code is simplified for clarity:</p>

<p><div>
<pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SessionsController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> new
    <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:installer</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      render <span style="color:#ff3333; font-weight:bold;">:layout</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'installer_signup'</span>, <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'installer_signup'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      render <span style="color:#ff3333; font-weight:bold;">:layout</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'modal'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:username</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">blank</span>?
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Please enter a username&quot;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render_new_action
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">unless</span> user = User.<span style="color:#9900CC;">authenticate</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:username</span><span style="color:#006600; font-weight:bold;">&#93;</span>, params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:password</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Sorry, that username was not recognised&quot;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render_new_action
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    set_logged_in_user<span style="color:#006600; font-weight:bold;">&#40;</span>user<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:installer</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#0066ff; font-weight:bold;">@username</span> = user.<span style="color:#9900CC;">username</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:template</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'installer_done'</span>, <span style="color:#ff3333; font-weight:bold;">:layout</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'installer_signup'</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">elsif</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:third_party</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:template</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;third_party/#{params[:third_party]}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>success_url<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre>
</div></p>

<p>Notice how the conditional logic has a similar structure in both actions. Our refactoring starts by introducing a before_filter which works out the necessary extension:</p>

<p><div>
<pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SessionsController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
&nbsp;
  before_filter <span style="color:#ff3333; font-weight:bold;">:extend_for_client</span>
&nbsp;
  ....
&nbsp;
  <span style="color:#9900CC;">private</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> extend_for_client
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">extend</span><span style="color:#006600; font-weight:bold;">&#40;</span>client_exension_module<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> client_exension_module
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> client_extension_module
    <span style="color:#0000FF; font-weight:bold;">return</span> InstallerClient <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:installer</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> ThirdPartyClient <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:third_party</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">module</span> InstallerClient
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">module</span> ThirdPartyClient
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre>
</div></p>

<p>Notice that we don&#8217;t bother extending the controller for the &#8216;else&#8217; case of the conditional statements &#8211; we&#8217;ll leave that behaviour in the base controller, only overriding it where necessary.</p>

<p>Now let&#8217;s extract the client-specific code out of the create action into a method that we&#8217;ll override in the modules:</p>

<p><div>
<pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SessionsController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
&nbsp;
  ...
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:username</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">blank</span>?
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Please enter a username&quot;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render_new_action 
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">unless</span> user = User.<span style="color:#9900CC;">authenticate</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:username</span><span style="color:#006600; font-weight:bold;">&#93;</span>, params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:password</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Sorry, that username was not recognised&quot;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render_new_action 
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    set_logged_in_user<span style="color:#006600; font-weight:bold;">&#40;</span>user<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    handle_successful_login
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  private 
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> handle_successful_login
    <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:installer</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#0066ff; font-weight:bold;">@username</span> = user.<span style="color:#9900CC;">username</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:template</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'installer_done'</span>, <span style="color:#ff3333; font-weight:bold;">:layout</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'installer_signup'</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">elsif</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:third_party</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:template</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;third_party/#{params[:third_party]}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>success_url<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  ...</pre>
</div></p>

<p>Finally, we can the client-specific code into the appropriate module, leaving the default behaviour in the controller:</p>

<p><div>
<pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SessionsController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
&nbsp;
  before_filter <span style="color:#ff3333; font-weight:bold;">:extend_for_client</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> new
    render <span style="color:#ff3333; font-weight:bold;">:layout</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'modal'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:username</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">blank</span>?
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Please enter a username&quot;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render_new_action 
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">unless</span> user = User.<span style="color:#9900CC;">authenticate</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:username</span><span style="color:#006600; font-weight:bold;">&#93;</span>, params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:password</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Sorry, that username was not recognised&quot;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render_new_action 
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    set_logged_in_user<span style="color:#006600; font-weight:bold;">&#40;</span>user<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    handle_successful_login
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  private 
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> handle_successful_login
    <span style="color:#0000FF; font-weight:bold;">return</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>success_url<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  private
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> extend_for_client
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">extend</span><span style="color:#006600; font-weight:bold;">&#40;</span>client_exension_module<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> client_exension_module
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> client_extension_module
    <span style="color:#0000FF; font-weight:bold;">return</span> InstallerClient <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:installer</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> ThirdPartyClient <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:third_party</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">module</span> InstallerClient
    <span style="color:#9966CC; font-weight:bold;">def</span> new
      render <span style="color:#ff3333; font-weight:bold;">:layout</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'installer_signup'</span>, <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'installer_signup'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    private 
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> handle_successful_login
      <span style="color:#0066ff; font-weight:bold;">@username</span> = user.<span style="color:#9900CC;">username</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> render<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:template</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'installer_done'</span>, <span style="color:#ff3333; font-weight:bold;">:layout</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'installer_signup'</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">module</span> ThirdPartyClient
    <span style="color:#9966CC; font-weight:bold;">def</span> handle_successful_login
      <span style="color:#0000FF; font-weight:bold;">return</span> render<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:template</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;third_party/#{params[:third_party]}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre>
</div></p>

<p>Polymorphism is one of the power-features of an object-oriented language, and Ruby&#8217;s ability to flex this muscle at run-time opens up some really elegant options.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattwynne.net/2009/07/11/rails-tip-use-polymorphism-to-extend-your-controllers-at-runtime/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lessons From a Master</title>
		<link>http://blog.mattwynne.net/2008/03/22/lessons-from-a-master/</link>
		<comments>http://blog.mattwynne.net/2008/03/22/lessons-from-a-master/#comments</comments>
		<pubDate>Sat, 22 Mar 2008 20:34:43 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Agile / Lean Software Development]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[lean]]></category>
		<category><![CDATA[martinfowler]]></category>
		<category><![CDATA[refactoring]]></category>

		<guid isPermaLink="false">http://blog.mattwynne.net/2008/03/22/lessons-from-a-master/</guid>
		<description><![CDATA[One of the several great things about working for my current client is that their high public profile means it&#8217;s reasonably easy to get interesting people to come and visit us from time to time. Last week the mighty Martin Fowler dropped by to talk to us. I was lucky enough to spend a few [...]]]></description>
			<content:encoded><![CDATA[<p>One of the several great things about working for my current client is that their high public profile means it&#8217;s reasonably easy to get interesting people to come and visit us from time to time.</p>

<p>Last week the mighty <a href="http://martinfowler.com">Martin Fowler</a> dropped by to talk to us.</p>

<p><span id="more-43"></span></p>

<p>I was lucky enough to spend a few hours in Martin&#8217;s company, sharing lunch in the canteen with him and a few other senior technical bods, listening to his talk and Q&amp;A, then as he visited the various teams, taking a look at how we do things.</p>

<p>His talk lasted just over an hour, and was delivered with great panache, especially considering it was entirely off the cuff. Beginning with his experiences in software design right through his career, he described key lessons learned, building up to an inspirational tub-thumping call to arms for the British media (and my client in particular) to continue to battle the &#8216;information wasteland&#8217; coming out of the American commercial media. Fantastic stuff.</p>

<p>I made several notes during his talk and I thought I&#8217;d jot them down here.</p>

<hr />

<p>A lot of good ideas in software get lost though the generations. Part of the responsibility for this lies with the old-timers who don&#8217;t take adequate steps to communicate their ideas and lessons they&#8217;ve learned to the younger generation. Martin sees it as his main aim nowadays: to look backward, spot patterns, and try to communicate those through his books and talks.</p>

<p>The best ideas and techniques span multiple languages and technologies. By moving back and forth between the C++ and SmallTalk communities in his early days as a programmer, Martin was able to cross-pollinate ideas between the two, and filter out the most powerful concepts &#8211; those which applied to both.</p>

<p>Irreversible decisions are the most dangerous kind for any organisation. Lean (and thence Agile) principles try to make as many decisions as possible <strong>re</strong>versible, and to defer for as long as possible those which appear not to be. Largely, this is achieved by moving rapidly in small, safe steps so that the path backwards is always clear. Thus a big and risky task becomes smaller and more approachable.</p>

<p>Don&#8217;t accept that something can&#8217;t be changed &#8211; just try to figure out how.</p>

<p>If something is awkward and painful (e.g. database refactoring) then do it as often as possible, until it becomes easy.</p>

<p>Collaboration with the customer is key and to that end, the creation of a <strong>ubiquitous language</strong> is key. Other tools that can help with this collaboration are UML diagrams (as sketched on a whiteboard), CRC cards and tests.</p>

<p>The most important skill for a software developer is to be able to collaborate with people. The traditional view that mathematical skills are the most important is becoming redundant.</p>

<p>When designing code, two main features make for a good design:</p>

<ul>
<li>Lack of duplication</li>
<li>Clear reveal of intent</li>
</ul>

<p>To enable clarity of intent, naming is extremely important.</p>

<p>When designing a system, one approach is to think of modules as things which keep secrets, then partition your design around the secrets that need to be kept.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mattwynne.net/2008/03/22/lessons-from-a-master/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

