<?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>While I Compile</title>
	<atom:link href="http://whileicompile.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://whileicompile.com</link>
	<description>... I compile my thoughts</description>
	<lastBuildDate>Wed, 08 May 2013 22:24:53 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>The asp.net-mvc predicate</title>
		<link>http://whileicompile.com/2012/07/the-asp-net-mvc-predicate/</link>
		<comments>http://whileicompile.com/2012/07/the-asp-net-mvc-predicate/#comments</comments>
		<pubDate>Mon, 09 Jul 2012 16:11:15 +0000</pubDate>
		<dc:creator>John MacIntyre</dc:creator>
				<category><![CDATA[Career]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Insights]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Programmers]]></category>
		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://whileicompile.com/?p=675</guid>
		<description><![CDATA[I have a theory that you can tell if a Microsoft web de [...]]]></description>
				<content:encoded><![CDATA[<p>I have a theory that you can tell if a Microsoft web developer is good or not based on as single question.</p>
<blockquote><p><em>Would you choose webforms or MVC on a new project?</em></p></blockquote>
<p>Many readers probably consider this obvious, perhaps even equivalent to the choice between punch cards vs keyboard/monitor. I suspect most people reading this consider asp.net-MVC the logical choice, and only an idiot would choose otherwise</p>
<p>However, I suspect most Microsoft web application developers would still chose webforms &#8230; scary as that is.</p>
<p>I think that right now, MVC has really separated the good from the bad, at least as far as asp.net developers go. Developers on top of their game have at least overview experience with MVC, yet most weak or lazy developers haven’t been forced to make the leap yet, as a result they either haven’t looked into it, or have been so confounded by the paradigm shift that they’ve passed it off as a trendy fad.</p>
<p>Please notice I said ‘choose on a new project’, not ‘currently working in’. I’m sure there are many developers who are working in webforms who would prefer to be working in MVC &#8230; I’m one of them. On the flip side, I recently met a developer working in an MVC app who wishes it was webforms.</p>
<p>There is a presumption in my statement, that MVC is inherently better than webforms. To most of us, this seems obvious, but there are many who disagree &#8230; and that’s fine. However, I’ve yet to find a valid argument for webforms over MVC.</p>
<p>&#8230; don’t get me wrong, I’ve heard people tell me that webforms is better, but I’ve never heard a rational argument. Those who have tried have basically given me buzzwords like ‘event-driven’ but fail to contrast it against, or even recognize the cost of that paradigm.</p>
<p>Take for example; answers to this Stackoverflow question <a title="Stackoverflow - When to favor webforms over MVC?" href="http://programmers.stackexchange.com/questions/95212/when-to-favor-webforms-over-mvc">When to favor webforms over MVC?</a> I’m not going to argue about integrating MVC into an existing webforms app because I think maintaining technology consistency is important. But some of the other reasons include :</p>
<ol>
<li>Leveraging existing training – True, but good developers usually keep their skills up to date, so is this really that big of a deal?</li>
<li>View/edit modes makes duplicate work – This is actually better than all edit pages, yes &#8230; even for enterprise apps. If you don’t believe me, just think about all the functionality you added to ensure users couldn’t ‘save’ &#8230; there’s no save button issues when they can’t even access the edit form.</li>
<li>Too many files – Don’t forget all those files allow for Single Responsibility and Separation of Concerns.  Basically they encourage a cleaner code base.</li>
<li>Issues with the master page consistency – This sounds more like an application issue than a framework issue.</li>
<li>Recognizable directory structure – You quickly get used to the MVC directory structure, and basic routing isn&#8217;t rocket science.</li>
<li>Powerful controls – True, but all that functionality will be ported to the MVC paradigm eventually. And for what it’s worth, I think partials are better than user controls.</li>
<li>Webforms is a shortcut to web development for Windows developers – True, but isn’t this the epitome of a bad dev? They don’t want to actually learn the tools they’re working with?</li>
<li>Views &amp; controllers are combined in webforms – True, but separating them makes good programming practice like the Single Responsibility principle possible.</li>
<li>Somebody even suggested the page lifecycle gives you more control – Wow. Place a delete button on a grid row, then tell me this when you have to load the grid twice in your postback; once in the Load event to wire up the event logic, and again after you delete the data.</li>
</ol>
<p>But the biggest reason cited everywhere seems to be ‘personal choice’. &#8230; LOL &#8230; yeah, if you’re smart you’ll go with MVC, if you don’t know MVC, don’t understand it, and don’t want to learn it, you chose webforms.</p>
<p>BTW, it’s not even about webforms sucking. Webforms has a lot of stuff to avoid, but it’s not <em>just</em> about that &#8230;. <em>MVC is an enabler</em>. Basically the MVC paradigm dove tails with so many good practices which are difficult in webforms (at best), like; Unit Testing (and easy mocking), Clean code, Separation of Concerns, Single Responsibility Principle, etc&#8230;  I’d even venture to bet there’s a noticeable correlation between modern software development processes (like agile) in MVC teams.</p>
<p>There’s a possibility this is a temporary thing, but I suspect it will last a lot longer than anybody expects, because bad developers don’t move to a new platform unless they’re forced. And judging by Microsoft’s continued “MVC doesn’t replace webforms” stance, it doesn’t look like they’ll be forced for a while.</p>
<p>Now as far as the ‘business reasons’ for choosing webforms go, having an abundance of developers, doesn’t really wash. At least it doesn’t if you bought into my opinion that webforms projects will attract low quality developers, and repel high quality devs.</p>
<p>What if businesses chose MVC for ‘business reasons’? Instead of aiming for an ‘abundance’ of devs, they aim for good devs, and plan to pay their slightly higher rates with the dramatic savings in development and maintenance?</p>
<p><em>PS-I sincerely looked for a good reason to chose webforms over MVC. If you know of any good reasons to choose it over MVC, please leave a comment or send me an email.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://whileicompile.com/2012/07/the-asp-net-mvc-predicate/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A simple proposal to rule out obvious software patents</title>
		<link>http://whileicompile.com/2012/06/a-simple-proposal-to-rule-out-obvious-software-patents/</link>
		<comments>http://whileicompile.com/2012/06/a-simple-proposal-to-rule-out-obvious-software-patents/#comments</comments>
		<pubDate>Mon, 25 Jun 2012 16:25:49 +0000</pubDate>
		<dc:creator>John MacIntyre</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Innovation]]></category>
		<category><![CDATA[Software-Industry]]></category>
		<category><![CDATA[Software-Patents]]></category>

		<guid isPermaLink="false">http://whileicompile.com/?p=668</guid>
		<description><![CDATA[I just read the EFF’s new website (https://defendinnova [...]]]></description>
				<content:encoded><![CDATA[<p>I just read the EFF’s new website (<a href="https://defendinnovation.org/">https://defendinnovation.org/</a>) about how to change the patent system to prevent the patent trolls from stifling innovation.  I like some of the ideas, but question how realistic others are (i.e. #3? – C’mon; How many implementations in how many languages will you need to write to cover all your bases?)</p>
<p>I realize this is an extremely naive statement to make, but I’m going to make it anyway; solving the ‘non-obvious’ aspect of a software patent is simple.</p>
<p>&#8230; and it doesn’t involve <a title="Should People Learn To Code? Yes – If They Are Judges Ruling On Cases Involving Software" href="http://www.techdirt.com/articles/20120518/04252818965/should-people-learn-to-code-yes-if-they-are-judges-ruling-cases-involving-software.shtml">judges learning to code</a>.</p>
<p>Here’s my proposal:  Software patent proposals should include a unit test suite and a single solution implementation.  The test suite would be made public immediately, without the implemented solution.  The public would take a crack at making the test suite pass.</p>
<p>If there are no successful passes, then it could be deemed as a difficult problem with a non-obvious solution.</p>
<p>If the patent office is bombarded with working solutions, then it unquestionably fails the ‘non-obvious’ test.</p>
<p>It’s debatable what to do if a relative few brilliant developers solve it, while most fail.  But this would definitely eliminate laughable patents like Amazon’s 1-Click which would have bombarded the patent office in less than an hour.</p>
]]></content:encoded>
			<wfw:commentRss>http://whileicompile.com/2012/06/a-simple-proposal-to-rule-out-obvious-software-patents/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>My take on identifier semantics (Id vs No vs Code vs Key)</title>
		<link>http://whileicompile.com/2012/03/my-take-on-identifier-semantics-id-vs-no-vs-code-vs-key/</link>
		<comments>http://whileicompile.com/2012/03/my-take-on-identifier-semantics-id-vs-no-vs-code-vs-key/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 21:21:52 +0000</pubDate>
		<dc:creator>John MacIntyre</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[conventions]]></category>
		<category><![CDATA[semantics]]></category>

		<guid isPermaLink="false">http://whileicompile.com/?p=660</guid>
		<description><![CDATA[My simple conventions for these popular identifier names.  I don't believe they're all the same, and should be used under different circumstances.]]></description>
				<content:encoded><![CDATA[<p>When I design my own software, I have a naming convention that I use. It’s not rocket science, but it’s allowed me to know exactly what something is as soon as I see the name.</p>
<p>Unfortunately, while other developers use the same names, they often use them in ways you don’t expect. I kind of wish everybody would use this simple convention.</p>
<p>So here it is:</p>
<p><strong>Id</strong> – In my little world, any variable or database column including the term ‘Id’ is an integer identifier for something. Usually non-negative and non-zero. I suppose it could be negative, although I would never do it, but it should never be zero since in many languages uninitialized variables default to 0. As is conventional, this is always my primary or foreign key.</p>
<p><strong>No</strong> or<strong> Number</strong> – I use the term ‘No’ or ‘Number’ for alphanumeric identifiers usually. Why am I calling a string ‘Number’? Because that’s how we communicate; Customer Number, Item Number, Vendor Number, etc&#8230; Identifiers with the word ‘Number’ in them are almost always strings, even our phone number or Social Security Number, which are made up of only digits, are usually stored as character strings by experienced developers.</p>
<p><strong>Cd</strong> or <strong>Code</strong> – I use this for specific length identifiers which don’t change often. For example: State Codes (‘NY’, ‘WA’), order types, credit card types, etc&#8230;. I create enums for these values and evaluate them in the display instead of the database; I’ve just found that infrequent code changes make fewer joins on every query seem like a good trade off. Codes are also almost always displayed as drop down lists on the screen and their abbreviation makes direct database easier as well (as opposed to having a provinces table, and a province id of 3).</p>
<p><strong>Key</strong> –I don’t use this term very much, but I would use it for something like an application key rather than an identifier and it would be an alpha-numeric string.</p>
<p>This is pretty basic, but consistency counts. Running into variables named UserId instead of UserName, and then XxxUserId for the user id adds nothing but confusion. Even after seeing it for months, it will still throw you off, and when you create a new method requiring a user id as a parameter, do you call it userId? Or xxxUserId? And when it’s named with a prefix like this, it’s not even like it comes up in autosuggest to constantly remind you of the difference. Yes, you *could* rename the variables all throughout your code, but then you’ve still got it in the database which has a lot more dependencies, many of which are undocumented. &#8230; but I digress &#8230;</p>
<p>I should also point out, there are times when I don’t follow these conventions, for example, I don’t call user names ‘User Number’, nor do I call ‘UPC’ (Universal Product Code) a ‘Universal Product Number’ as my definitions might suggest. But for the most part, every app I’ve designed in the past 10 years has this convention.</p>
<p>One more thing, if I’m generating these strings, I never use vowels, since it’s only a matter of time before something offensive is generated. You can check for the obvious swear words, but you won’t catch them all &#8230; but without vowels, nothing will get through, ever. Even something which appears as though it might be offensive, without vowels, it will be chalked up as an overly active imagination.</p>
]]></content:encoded>
			<wfw:commentRss>http://whileicompile.com/2012/03/my-take-on-identifier-semantics-id-vs-no-vs-code-vs-key/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Discovering Typemock</title>
		<link>http://whileicompile.com/2012/02/discovering-typemock/</link>
		<comments>http://whileicompile.com/2012/02/discovering-typemock/#comments</comments>
		<pubDate>Fri, 24 Feb 2012 19:00:30 +0000</pubDate>
		<dc:creator>John MacIntyre</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[moq]]></category>
		<category><![CDATA[typemock]]></category>
		<category><![CDATA[unit-testing]]></category>

		<guid isPermaLink="false">http://whileicompile.com/?p=639</guid>
		<description><![CDATA[Frustration mocking static methods, the ridiculous hoops I was forced to jump through, and the clean implementation I was finally able to do with Typemock.]]></description>
				<content:encoded><![CDATA[<p>Over Christmas I started a little MVC app and because I want it to be a production quality app, and live for a long time, I decided to write unit tests for the whole thing. I don’t know if it will be 100% coverage, but ideally, I’d like it to be close.</p>
<p>So, before I even wrote a line of my own code, I started writing tests for the generated code, and as you might expect, it wasn’t long before I started running into static methods which cannot be mocked with Moq (the mocking framework I was using).</p>
<p>Here’s an example of an action method I tested:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008000;">&#91;</span>HttpPost<span style="color: #008000;">&#93;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> ActionResult LogOn<span style="color: #008000;">&#40;</span>LogOnModel model, <span style="color: #6666cc; font-weight: bold;">string</span> returnUrl<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>ModelState<span style="color: #008000;">.</span><span style="color: #0000FF;">IsValid</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>Membership<span style="color: #008000;">.</span><span style="color: #0000FF;">ValidateUser</span><span style="color: #008000;">&#40;</span>model<span style="color: #008000;">.</span><span style="color: #0000FF;">UserName</span>, model<span style="color: #008000;">.</span><span style="color: #0000FF;">Password</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
  FormsAuthentication<span style="color: #008000;">.</span><span style="color: #0000FF;">SetAuthCookie</span><span style="color: #008000;">&#40;</span>model<span style="color: #008000;">.</span><span style="color: #0000FF;">UserName</span>, model<span style="color: #008000;">.</span><span style="color: #0000FF;">RememberMe</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>Url<span style="color: #008000;">.</span><span style="color: #0000FF;">IsLocalUrl</span><span style="color: #008000;">&#40;</span>returnUrl<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;</span>amp<span style="color: #008000;">;&amp;</span>amp<span style="color: #008000;">;</span> returnUrl<span style="color: #008000;">.</span><span style="color: #0000FF;">Length</span> <span style="color: #008000;">&amp;</span>gt<span style="color: #008000;">;</span> <span style="color: #FF0000;">1</span> <span style="color: #008000;">&amp;</span>amp<span style="color: #008000;">;&amp;</span>amp<span style="color: #008000;">;</span> returnUrl<span style="color: #008000;">.</span><span style="color: #0000FF;">StartsWith</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;/&quot;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">!</span>returnUrl<span style="color: #008000;">.</span><span style="color: #0000FF;">StartsWith</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;//&quot;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;</span>amp<span style="color: #008000;">;&amp;</span>amp<span style="color: #008000;">;</span> <span style="color: #008000;">!</span>returnUrl<span style="color: #008000;">.</span><span style="color: #0000FF;">StartsWith</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;/<span style="color: #008080; font-weight: bold;">\&quot;</span>))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction(&quot;</span>Index<span style="color: #666666;">&quot;, &quot;</span>Home<span style="color: #666666;">&quot;);
}
}
else
{
ModelState.AddModelError(&quot;</span><span style="color: #666666;">&quot;, &quot;</span>The user name or password provided <span style="color: #008000;">is</span> incorrect<span style="color: #008000;">.</span><span style="color: #666666;">&quot;);
}
}
&nbsp;
// If we got this far, something failed, redisplay form
return View(model);
}</span></pre></td></tr></table></div>

<p>Notice, the Membership.ValidateUser() &amp; FormsAuthentication.SetAuthCookie() methods are static and untestable.</p>
<p>The strategy I found for testing these methods was to create wrappers, so I created the following classes.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> MembershipWrapper <span style="color: #008000;">:</span> IMembershipWrapper
<span style="color: #008000;">&#123;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">bool</span> ValidateUser<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> userName, <span style="color: #6666cc; font-weight: bold;">string</span> password<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #0600FF; font-weight: bold;">return</span> Membership<span style="color: #008000;">.</span><span style="color: #0000FF;">ValidateUser</span><span style="color: #008000;">&#40;</span>userName, password<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>and</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> FormsAuthenticationWrapper <span style="color: #008000;">:</span> IFormsAuthenticationWrapper
<span style="color: #008000;">&#123;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SetAuthCookie<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> userName, <span style="color: #6666cc; font-weight: bold;">bool</span> rememberMe<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
FormsAuthentication<span style="color: #008000;">.</span><span style="color: #0000FF;">SetAuthCookie</span><span style="color: #008000;">&#40;</span>userName, rememberMe<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>And a couple interfaces</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">interface</span> IMembershipWrapper
<span style="color: #008000;">&#123;</span>
<span style="color: #6666cc; font-weight: bold;">bool</span> ValidateUser<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> userName, <span style="color: #6666cc; font-weight: bold;">string</span> password<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>And</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">interface</span> IFormsAuthenticationWrapper
<span style="color: #008000;">&#123;</span>
<span style="color: #6666cc; font-weight: bold;">void</span> SetAuthCookie<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> userName, <span style="color: #6666cc; font-weight: bold;">bool</span> rememberMe<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Not exactly rocket science.</p>
<p>Once I finished that, I also had to handle the Controller.Url property. I used <a title="How to mock Controller.Url" href="http://thoai-nguyen.blogspot.com/2011/07/how-to-mock-urlhelper.html">a technique I found</a> at <a title="Van T Nguyen on Twitter" href="https://twitter.com/#!/nvthoai">@nvthoai</a>’s site.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">interface</span> IUrlHelperWrapper
<span style="color: #008000;">&#123;</span>
<span style="color: #6666cc; font-weight: bold;">string</span> Action<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> actionName, <span style="color: #6666cc; font-weight: bold;">string</span> controllerName<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #6666cc; font-weight: bold;">string</span> Action<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> actionName, <span style="color: #6666cc; font-weight: bold;">string</span> controllerName, <span style="color: #6666cc; font-weight: bold;">object</span> routeValues<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #6666cc; font-weight: bold;">string</span> Action<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> actionName, <span style="color: #6666cc; font-weight: bold;">string</span> controllerName, RouteValueDictionary routeValues<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #6666cc; font-weight: bold;">bool</span> IsLocalUrl<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> url<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> UrlHelperWrapper <span style="color: #008000;">:</span> UrlHelper, IUrlHelperWrapper
<span style="color: #008000;">&#123;</span>
<span style="color: #0600FF; font-weight: bold;">internal</span> UrlHelperWrapper<span style="color: #008000;">&#40;</span>RequestContext requestContext<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">:</span> <span style="color: #0600FF; font-weight: bold;">base</span><span style="color: #008000;">&#40;</span>requestContext<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">internal</span> UrlHelperWrapper<span style="color: #008000;">&#40;</span>RequestContext requestContext, RouteCollection routeCollection<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">:</span> <span style="color: #0600FF; font-weight: bold;">base</span><span style="color: #008000;">&#40;</span>requestContext, routeCollection<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">public</span> UrlHelperWrapper<span style="color: #008000;">&#40;</span>UrlHelper helper<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">:</span> <span style="color: #0600FF; font-weight: bold;">base</span><span style="color: #008000;">&#40;</span>helper<span style="color: #008000;">.</span><span style="color: #0000FF;">RequestContext</span>, helper<span style="color: #008000;">.</span><span style="color: #0000FF;">RouteCollection</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Then I had to create class member variables in the controller</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">private</span> IMembershipWrapper membership<span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #008000;">new</span> IUrlHelperWrapper Url<span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">private</span> IFormsAuthenticationWrapper authentication<span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>And new constructors</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> AccountController<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">:</span><span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> MembershipWrapper<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>,<span style="color: #008000;">new</span> FormsAuthenticationWrapper<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">public</span> AccountController<span style="color: #008000;">&#40;</span>IMembershipWrapper membershipObject,
IFormsAuthenticationWrapper formsAuthenticationObject,
IUrlHelperWrapper urlHelper<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">membership</span> <span style="color: #008000;">=</span> membershipObject<span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Url</span> <span style="color: #008000;">=</span> urlHelper<span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">authentication</span> <span style="color: #008000;">=</span> formsAuthenticationObject<span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Then override the Initialize method in order to setup my UrlHelperWrapper.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #6666cc; font-weight: bold;">void</span> Initialize<span style="color: #008000;">&#40;</span>RequestContext requestContext<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #0600FF; font-weight: bold;">base</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Initialize</span><span style="color: #008000;">&#40;</span>requestContext<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">if</span><span style="color: #008000;">&#40;</span>Url <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
Url <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> UrlHelperWrapper<span style="color: #008000;">&#40;</span>requestContext<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>And finally, I changed the LogOn method to use the new wrappers instead of the static methods.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008000;">...</span>
<span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>membership<span style="color: #008000;">.</span><span style="color: #0000FF;">ValidateUser</span><span style="color: #008000;">&#40;</span>model<span style="color: #008000;">.</span><span style="color: #0000FF;">UserName</span>, model<span style="color: #008000;">.</span><span style="color: #0000FF;">Password</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
authentication<span style="color: #008000;">.</span><span style="color: #0000FF;">SetAuthCookie</span><span style="color: #008000;">&#40;</span>model<span style="color: #008000;">.</span><span style="color: #0000FF;">UserName</span>, model<span style="color: #008000;">.</span><span style="color: #0000FF;">RememberMe</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">...</span></pre></td></tr></table></div>

<p>Ok, yeah; nothing in there is rocket science. I admit it, and when you know what to do, it’s not difficult. However, a few things become painfully obvious when you do this:</p>
<p>1. 100% code coverage not only isn’t practical, it’s not even possible since the wrappers cannot be tested.</p>
<p>2. You’ll have to create a new wrapper for every static method you ever use. I suppose you could use one wrapper for all static methods, but I prefer to keep the class names lined up.</p>
<p>3. I need to pass a wrapper instance into the constructor for every wrapper my testing *class* contains, as opposed to the *Action* I’m testing.</p>
<p>4.I have to design my code in a specific way (a way which I would NEVER do on my own) in order to make it testable.</p>
<p>So my test winds up looking like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008000;">&#91;</span>TestMethod<span style="color: #008000;">&#93;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> Logon_ValidReturnUrl_ReturnsRedirectToUrl<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008080; font-style: italic;">// Arrange</span>
Mock membership <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Mock<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
membership<span style="color: #008000;">.</span><span style="color: #0000FF;">Setup</span><span style="color: #008000;">&#40;</span>m <span style="color: #008000;">=&amp;</span>gt<span style="color: #008000;">;</span> m<span style="color: #008000;">.</span><span style="color: #0000FF;">ValidateUser</span><span style="color: #008000;">&#40;</span>It<span style="color: #008000;">.</span><span style="color: #0000FF;">IsAny</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, It<span style="color: #008000;">.</span><span style="color: #0000FF;">IsAny</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Returns</span><span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
Mock authenticator <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Mock<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
Mock urlHelper <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Mock<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
urlHelper<span style="color: #008000;">.</span><span style="color: #0000FF;">Setup</span><span style="color: #008000;">&#40;</span>h <span style="color: #008000;">=&amp;</span>gt<span style="color: #008000;">;</span> h<span style="color: #008000;">.</span><span style="color: #0000FF;">IsLocalUrl</span><span style="color: #008000;">&#40;</span>It<span style="color: #008000;">.</span><span style="color: #0000FF;">IsAny</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Returns</span><span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">var</span> controller <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> AccountController<span style="color: #008000;">&#40;</span>membership<span style="color: #008000;">.</span><span style="color: #6666cc; font-weight: bold;">Object</span>, authenticator<span style="color: #008000;">.</span><span style="color: #6666cc; font-weight: bold;">Object</span>, urlHelper<span style="color: #008000;">.</span><span style="color: #6666cc; font-weight: bold;">Object</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">var</span> model <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> LogOnModel<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">string</span> testUrl <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;/something/inteREsting/2/ensure/test/returns/correct/url/&quot;</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #008080; font-style: italic;">// Act</span>
ActionResult result <span style="color: #008000;">=</span> controller<span style="color: #008000;">.</span><span style="color: #0000FF;">LogOn</span><span style="color: #008000;">&#40;</span>model, testUrl<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #008080; font-style: italic;">// Assert</span>
Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsNotNull</span><span style="color: #008000;">&#40;</span>result<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsInstanceOfType</span><span style="color: #008000;">&#40;</span>result, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>RedirectResult<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">var</span> redirectResult <span style="color: #008000;">=</span> result <span style="color: #0600FF; font-weight: bold;">as</span> RedirectResult<span style="color: #008000;">;</span>
Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span>testUrl, redirectResult<span style="color: #008000;">.</span><span style="color: #0000FF;">Url</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Now when I look at that test, and especially as the number of controller constructor parameters starts growing, and I add more tests with similar ‘arrange’ sections, I feel compelled to start cleaning and organizing my test code. I suddenly want to create test class member variables for each of the mocks required by the constructor, and add other overhead &#8230; I’m unsatisfied with the above code and really, really, want to clean it up.</p>
<p>So after spending a weekend writing that crap instead of adding features, I was sufficiently frustrated, and spent my drive to work Monday morning thinking about it. Mostly, I wondered long and hard about if tests are considered ‘waste’ from a Lean Startup point of view. And to be honest, I was really leaning toward &#8230; ‘yes: they’re waste’.</p>
<p>Then when I got to work, I was tasked with the challenge of how to unit test a webforms application, which is really a question of ‘How can we mock it?’ This search led me to <a title="Ivonna" href="http://ivonna.biz/">Ivonna</a>, which looked great but relies on <a title="Typemock Isolator" href="http://www.typemock.com/typemock-isolator-product3">TypeMock Isolator</a>.</p>
<p>Now I’ve heard of Typemock before, I’ve actually followed them on Twitter for at least a year, but never really looked into it. To make a long story short, I was a little surprised by the price, and really couldn’t understand why anybody would pay when there are so many free mocking tools.</p>
<p>That’s when I found out I can mock static methods &#8230; which as you can imagine, after that weekend, I was intrigued to put it mildly &#8230;. actually ‘converted to fanboy’ status is probably a little more accurate. <img src='http://whileicompile.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Here’s the same test on the original method using Typemock</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008000;">&#91;</span>TestMethod, Isolated<span style="color: #008000;">&#93;</span>
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> Logon_ValidReturnUrl_ReturnsRedirectToUrl<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008080; font-style: italic;">// Arrange</span>
<span style="color: #0600FF; font-weight: bold;">var</span> controller <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> AccountController<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
Isolate<span style="color: #008000;">.</span><span style="color: #0000FF;">WhenCalled</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">=&amp;</span>gt<span style="color: #008000;">;</span> Membership<span style="color: #008000;">.</span><span style="color: #0000FF;">ValidateUser</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Empty</span>, <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Empty</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">WillReturn</span><span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
Isolate<span style="color: #008000;">.</span><span style="color: #0000FF;">WhenCalled</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">=&amp;</span>gt<span style="color: #008000;">;</span> FormsAuthentication<span style="color: #008000;">.</span><span style="color: #0000FF;">SetAuthCookie</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Empty</span>, <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IgnoreCall</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
Isolate<span style="color: #008000;">.</span><span style="color: #0000FF;">WhenCalled</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">=&amp;</span>gt<span style="color: #008000;">;</span> controller<span style="color: #008000;">.</span><span style="color: #0000FF;">Url</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IsLocalUrl</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Empty</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">WillReturn</span><span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">var</span> model <span style="color: #008000;">=</span> Isolate<span style="color: #008000;">.</span><span style="color: #0000FF;">Fake</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Instance</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">const</span> <span style="color: #6666cc; font-weight: bold;">string</span> testUrl <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;/something/inteREsting/2/ensure/test/returns/correct/url/&quot;</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #008080; font-style: italic;">// Act</span>
ActionResult result <span style="color: #008000;">=</span> controller<span style="color: #008000;">.</span><span style="color: #0000FF;">LogOn</span><span style="color: #008000;">&#40;</span>model, testUrl<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #008080; font-style: italic;">// Assert</span>
Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsNotNull</span><span style="color: #008000;">&#40;</span>result<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">IsInstanceOfType</span><span style="color: #008000;">&#40;</span>result, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>RedirectResult<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">var</span> redirectResult <span style="color: #008000;">=</span> result <span style="color: #0600FF; font-weight: bold;">as</span> RedirectResult<span style="color: #008000;">;</span>
Assert<span style="color: #008000;">.</span><span style="color: #0000FF;">AreEqual</span><span style="color: #008000;">&#40;</span>testUrl, redirectResult<span style="color: #008000;">.</span><span style="color: #0000FF;">Url</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>When you compare this test with the test using <a title="Moq" href="http://code.google.com/p/moq/">Moq</a>, the differences are trivial, but I don’t feel compelled to ‘clean it’, and &#8230; get this &#8230;. I didn’t have to change anything in my app.</p>
<p>Let me repeat that, I didn’t have to change anything in my app. I didn’t have to write any wrapper classes, modify my constructors, pollute my class with unnecessary member variables, or spend 45 mintues trying to figure out how to mock the Controller.Url property, or put part of my wrapper initialization code into the Initialize method because I couldn’t initialize one of my wrappers in the constructor.</p>
<p>I mean all those changes just felt like a wretched code smell.</p>
<p>But the Typemock test was all straight forward. I felt like I sprayed my code with deodorizer.</p>
<p>Maybe I was using Moq the wrong way, but based on my research on StackOverflow, it seems that wrappers are the way everybody is managing this. If you know a better way, please let me know in the comments.</p>
<p>PS-Last week I sat in on a Typemock seminar, and the guy doing the seminar, <a title="Gil Zilberfeld" href="http://www.gilzilberfeld.com/">Gil Zilberfeld</a>, said something which really resonated with me, he said</p>
<blockquote><p>&#8220;If you&#8217;re doing things just for testing, you&#8217;re doing it wrong.&#8221;</p></blockquote>
<p>&#8230;. it’s as if he was talking directly to me.</p>
]]></content:encoded>
			<wfw:commentRss>http://whileicompile.com/2012/02/discovering-typemock/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Consultants are advisors, not decision makers.</title>
		<link>http://whileicompile.com/2011/02/consultants-are-advisors-not-decision-makers/</link>
		<comments>http://whileicompile.com/2011/02/consultants-are-advisors-not-decision-makers/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 15:18:00 +0000</pubDate>
		<dc:creator>John MacIntyre</dc:creator>
				<category><![CDATA[Consulting]]></category>
		<category><![CDATA[ethics]]></category>
		<category><![CDATA[Insights]]></category>

		<guid isPermaLink="false">http://whileicompile.wordpress.com/?p=608</guid>
		<description><![CDATA[Overview I was having lunch with my friend &#38; collea [...]]]></description>
				<content:encoded><![CDATA[<h2>Overview</h2>
<p>I was having lunch with my friend &amp; colleague last week and we had a disagreement about whose decision it is to make a change when you see something wrong in the client’s software.</p>
<h2>Mechanic analogy</h2>
<p>My colleague used an analogy about a mechanic; it was a good one, so I&#8217;ll use it here.</p>
<p>Let’s say you bring your car in for a $30 oil change, and your mechanic notices a problem with the timing belt.  My colleague suggests, he doesn’t just ignore it, he tells you it’s an emergency <strong>must</strong> be changed immediately (the emphasis is my friends).</p>
<p>Well I agree the mechanic shouldn’t just ignore it, and I was relieved my friend didn’t suggest the mechanic should simply change the timing belt, driving the bill from $30 to $930, but I’m not sure if telling the car owner they <em>must</em> change the timing belt ‘<em>now’</em> is appropriate either.</p>
<p>In my opinion the mechanic should <em>tell the customer what he found, the risk in not fixing it, outline the options to fix it, and the cost &amp; associated risk with each option</em><a href="#_ftn1" name="_ftnref1">[1]</a>.  Then make a recommendation.</p>
<p>It’s the customer’s decision, not the mechanics, and even if the customer makes a foolish decision, it’s his decision, not the mechanics.</p>
<p>Fortunately, all the mechanics I’ve dealt with seem to understand this.</p>
<h2>As consultants we’re advisors, not the decision maker</h2>
<p>In my opinion, our role as consultants / advisors includes the responsibility to inform the client of any problems or potential problems you’ve noticed, the risks in not fixing it, options to resolve the problem, along with the costs and risks associated with each.</p>
<h2>Unethical behaviour</h2>
<p>To me it seems unethical to go rogue, and just start making changes the client doesn’t know about, and didn’t approve.</p>
<p>It’s also unethical to purposely instil fear, uncertainty, and doubt when explaining the options to the client so they make the decision you want them to; regardless of your intentions.</p>
<h2>The client owns your time</h2>
<p>After all, the client does own the software, is responsible for its maintenance, and they do own your time to direct as necessary.</p>
<p>Wait, what?  Who owns your time?</p>
<p>Yeah, when you&#8217;re consulting, your client (or employer) owns your time.  … you sold it to them; remember?</p>
<p>Every consulting and/or employment agreement is different, but if you&#8217;re charging by the hour, it probably says something like this; they bought your focused efforts to solve their problems for a specific duration.</p>
<p>And how they spend your time (their resource) is up to them (within reason<a href="#_ftn2" name="_ftnref2">[2]</a>).</p>
<p>So deciding feature X is more important than feature Y, or bug X is more important than bug Y, is their call, not yours.</p>
<h2>An extreme example</h2>
<p>But what if it’s a big important issue?  What if it’s a major security flaw in the banking software you work on.  The flaw is dangerous. The flaw could potentially put users at risk. The flaw could even push the company into bankruptcy.</p>
<p>But your manager doesn&#8217;t want to invest the time to fix it and his manager stands behind him.  You&#8217;ve exhausted all other paths of reason, to the point of being on the verge of getting fired.</p>
<p>You still don&#8217;t have the right to change it … not even on your own time, because the software is their asset, not yours.</p>
<h2>Your decision</h2>
<p>Now I’m not saying you have no say, you can refuse.  Bottom line: if they refuse to make a change that you feel is necessary and/or potentially dangerous, you can give notice and quit.</p>
<h2>Exceptions</h2>
<p>Like everything, there are exceptions to this general rule.  Here are 2:</p>
<p>The first is if you are working on one task, notice another problem, and can fix it without seriously adjusting your time budget on the original task.  An example of this might be noticing and fixing a 1-off error in a loop.  I once had the responsibility of making manual year end changes to customer databases, with an estimated time of 3 days for each.  It took me 4 iterations working smart within the allotted time to write and test a utility which dropped that task to a 1 hour job<a href="#_ftn3" name="_ftnref3">[3]</a>.  The utility was separate, so I didn’t change the base product, and it cost my employer nothing.  So it is possible to make an impact working like this.</p>
<p>The second exception is you have built up a lot of trust with the client, and are completely unsupervised, making whatever changes deemed necessary to accomplish the client’s goals.  I’ve been in this situation a few times, and can honestly say, it’s a rare situation to be in.  It’s reserved for the situation where the client trusts your character and your responsibilities are so mysterious that they cannot make a decision, so they leave it up to you.<a href="#_ftn4" name="_ftnref4">[4]</a></p>
<h2>In Summary</h2>
<p>So basically, in my opinion, as consultants it’s not within our rights to make the decision to change or coerce the client into allowing you to change something.  It’s our obligation to inform them of the problem, outline their options along with the risks and cost of each, and make recommendations.</p>
<p>… that’s it.</p>
<div>
<hr size="1" />
<div>
<p><a href="#_ftnref1" name="_ftn1">[1]</a> Yeah, there aren’t too many options to discuss for changing a timing belt, but we’re discussing software remember.</p>
</div>
<div>
<p><a href="#_ftnref2" name="_ftn2">[2]</a> There are limits of course, everybody will have their own personal &amp; ethical limitation, and many (not enough though) will have professional limitations of what they&#8217;re willing to do.  Professional limitations might include, I was hired as a programmer, not a janitor, or worse yet, and Access developer.  ;-)h</p>
</div>
<div>
<p><a href="#_ftnref3" name="_ftn3">[3]</a> I could’ve dropped it to 5 minutes, but 1 hour is where the 80/20 principle told me to stop.  Somebody did this after I left, and it took significantly longer.</p>
</div>
<div>
<p><a href="#_ftnref4" name="_ftn4">[4]</a> Neither my colleague or I are currently in this situation.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://whileicompile.com/2011/02/consultants-are-advisors-not-decision-makers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Response to Seth Godin&#8217;s &#8211; Where do ideas come from?</title>
		<link>http://whileicompile.com/2010/11/response-to-seth-godins-where-do-ideas-come-from/</link>
		<comments>http://whileicompile.com/2010/11/response-to-seth-godins-where-do-ideas-come-from/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 18:29:10 +0000</pubDate>
		<dc:creator>John MacIntyre</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://whileicompile.wordpress.com/?p=598</guid>
		<description><![CDATA[Seth Godin is wrong I just read Seth Godin’s blog post  [...]]]></description>
				<content:encoded><![CDATA[<h2>Seth Godin is wrong</h2>
<p>I just read Seth Godin’s blog post <a href="http://sethgodin.typepad.com/seths_blog/2010/11/where-do-ideas-come-from.html">Where do ideas come from?</a> And in my opinion he completely missed it.</p>
<p>Sorry, I think Seth is awesome as do many others, but on this one, I don’t think he really answered the question; where do ideas come from?  Instead, in my opinion, what he wrote was more a list of favourable conditions</p>
<p>While I’m no Seth Godin, I’m going to share my understanding of ideas and their source<a name="_ftnref1" href="#_ftn1">[1]</a>.</p>
<p>I hope I don’t need to explain why a post about ideas and creativity is on a programming blog.</p>
<h2>Ideas come from questions</h2>
<p>Ideas are answers to those questions.</p>
<p>Although it may appear that ideas come out of nowhere while driving to work or zoning out in the shower, they are really answering previously asked questions burning in your subconscious.  There are many conditions which help answers come more easily, but they <em>never come if you don’t have the question</em> in the first place.</p>
<h2>Questions need to be installed into your subconscious</h2>
<p>A fleeting question doesn’t quite make it into your subconscious to be answered later.  The question needs to be important enough to be prioritized by your mind.</p>
<h2>Installations depth comes from emotion</h2>
<p>The importance of the question is largely based on the intensity of the emotion driving the question.  That’s why many innovations come during massive change and crisis.  Fear and greed inspire many ideas.</p>
<h2>New information is assimilated to answer these questions</h2>
<p>New questions are never installed for questions you already have the information needed to answer it.  So you need more information to answer the question and will need time to assimilate new information which is filtered against your question.</p>
<p>This information can be from; feedback from action, random thoughts in the shower, synergy, social media, blogs, news, conversations, books, radio, lectures, etc&#8230;  And yes, Seth even television<a href="#_ftn2" name="_ftnref2">[2]</a></p>
<h2>Fear constrains ideas</h2>
<p>Fear eliminates ideas.  Whether criticism of a bad idea, or constraint, or even a well-meaning, ‘helpful’ person who’s experienced proves it cannot be done.</p>
<p>When people fear criticism, ideas are never put forth which may inspire better ideas.  All ideas must be valued for an innovative environment.</p>
<h2>Forcing ideas constrains you to existing information</h2>
<p>You’ll hear many people say that you sit down, brainstorm, make your decisions quickly and take immediate action, which is great, when you have all the information you need.  But unless you have all the information you need, forcing it quickly usually won’t give you an awesome idea.</p>
<h2>Synergy is creativity&#8217;s compound interest</h2>
<p>Ideas usually require time, but they can be sped up with synergy<a name="_ftnref3" href="#_ftn3">[3]</a>.</p>
<p><em>Synergy is instantaneous compound interest for creativity.</em></p>
<p>One idea (good or bad) leads to another idea, then another, and another.  Before you know it, the feedback cycle has taken you down an entirely different path.</p>
<h2>But Seth was right about one thing</h2>
<p><em>Ideas that don&#8217;t ship are worthless</em></p>
<div>
<hr size="1" />
<div>
<p><a href="#_ftnref1" name="_ftn1">[1]</a> I’m also not a psychologist, so take this as more my own, possibly misunderstood, idea of how ideas happen.</p>
</div>
<div>
<p><a href="#_ftnref2" name="_ftn2">[2]</a> Television may not appear to be a motivator for ideas, because most people watch TV passively, but if your questions are installed deeply enough, it can still be a half decent source of information.</p>
</div>
<div>
<p><a href="#_ftnref3" name="_ftn3">[3]</a> I realize the word Synergy has been over used as a business buzzword, but it is a real concept.  Don’t let the buzzword throw you off.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://whileicompile.com/2010/11/response-to-seth-godins-where-do-ideas-come-from/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>My reaction to being named as a Canadian programmer worth following on Twitter</title>
		<link>http://whileicompile.com/2010/10/my-reaction-to-being-named-as-a-canadian-programmer-worth-following-on-twitter/</link>
		<comments>http://whileicompile.com/2010/10/my-reaction-to-being-named-as-a-canadian-programmer-worth-following-on-twitter/#comments</comments>
		<pubDate>Mon, 04 Oct 2010 15:33:50 +0000</pubDate>
		<dc:creator>John MacIntyre</dc:creator>
				<category><![CDATA[Non-Programming]]></category>

		<guid isPermaLink="false">http://whileicompile.wordpress.com/?p=592</guid>
		<description><![CDATA[Yesterday John Bristowe published a list of Developers  [...]]]></description>
				<content:encoded><![CDATA[<p>Yesterday <a href="http://twitter.com/jbristowe">John Bristowe</a> published a list of <a href="http://blogs.msdn.com/b/cdndevs/archive/2010/10/03/developers-in-canada-you-should-follow-on-twitter.aspx">Developers in Canada You Should Follow on Twitter</a>.</p>
<p>I was humbled and honoured to make the list. &#8230; actually, I was a little more excited than that, here&#8217;s a dramatization &#8230;.</p>
<p><a href="http://whileicompile.com/2010/10/my-reaction-to-being-named-as-a-canadian-programmer-worth-following-on-twitter/"><img src="http://i.ytimg.com/vi/kOTDn2A7hcY/0.jpg" alt="YouTube Video"></a></p>
<p>&#8230; Thanks John &#8230; I&#8217;ve been dying to use this video in a blog post.  <img src='http://whileicompile.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://whileicompile.com/2010/10/my-reaction-to-being-named-as-a-canadian-programmer-worth-following-on-twitter/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The UI programmers (not so) secret weapon</title>
		<link>http://whileicompile.com/2010/10/the-ui-programmers-not-so-secret-weapon/</link>
		<comments>http://whileicompile.com/2010/10/the-ui-programmers-not-so-secret-weapon/#comments</comments>
		<pubDate>Mon, 04 Oct 2010 03:11:03 +0000</pubDate>
		<dc:creator>John MacIntyre</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Clean-Code]]></category>
		<category><![CDATA[technique]]></category>

		<guid isPermaLink="false">http://whileicompile.wordpress.com/?p=571</guid>
		<description><![CDATA[An Example: Suppose you had software which matches buye [...]]]></description>
				<content:encoded><![CDATA[<h2>An Example:</h2>
<p>Suppose you had software which matches buyers and sellers, and new users are created via a ‘new user’ wizard<a href="#_ftn1" name="_ftnref1">[1]</a>.  Let’s say the wizard has 4 pages for Basic User Info, Review, Processing, and Completion Status Report.  And there are 5 buttons; Cancel, Previous, Next, Run, and Finish.</p>
<p>Cancel is displayed from the Basic User Info, Review, and Processing pages.<br />
Previous is displayed from the Review page.<br />
Next is displayed from the Basic User Info page.<br />
Run is displayed from the Review page.<br />
Finish is displayed from the Completion Status Report page.</p>
<p>This isn’t difficult to manage the display from the events<a href="#_ftn2" name="_ftnref2">[2]</a> right?</p>
<p>Well … in reality, it doesn’t take much of a change for your simple display functionality to become …</p>
<h2>The Problem</h2>
<p>Manipulating application display during events quickly turns into a complex, bug riddled, difficult to maintain, mess.</p>
<p>It may not seem like that big of a deal when you have only a few controls and a very simple (or no) workflow.  Actually, you may argue, managing visual display in the events may even <em>seem</em> like the most efficient strategy.  After all, you will never display, disable, or otherwise needlessly manipulate a control, but as your application grows more complex, this approach can leave you tearing your hair out<a href="#_ftn3" name="_ftnref3">[3]</a>.  This is especially true when you have multiple execution paths leading to the same event handlers with different state.</p>
<p>What if you received a change request for the above requirements, where additional info is required for buyers or sellers, resulting in a new wizard page for each, and in addition to that, business sellers require a page to gather Tax Information?</p>
<p>Your complexity has started to grow, resulting in buyers have a workflow of<br />
<em>Basic User Info -&gt; Buyer Info -&gt; Review -&gt; Processing -&gt; Completion Status Report</em></p>
<p>Individual sellers have a workflow of<br />
<em>Basic User Info -&gt; Individual Seller Info -&gt; Review -&gt; Processing -&gt; Completion Status Report</em></p>
<p>And commercial sellers have a workflow of<br />
<em>Basic User Info -&gt; Commercial Seller Info -&gt; Tax Info -&gt; Review -&gt; Processing -&gt; Completion Status Report</em></p>
<p>Notice how these changes lead to different execution paths all arriving at the Review page.  The question then, is; where does the back button on the Review page send the user?  The back button requires logic to know which wizard page to display.</p>
<p>It’s not difficult to imagine the need for logic to be added in more than one place<a href="#_ftn4" name="_ftnref4">[4]</a>, which can result in your display being processed differently from every event.  Not only does this lead to repeated code, but can also create bugs where buttons do/don’t display where they should.</p>
<p>Eventually, as this logic grows increasingly complex, simple, 5 minute, change requests will eventually take you hours to determine there won’t be any side effects.</p>
<p>At this point, developers usually find …</p>
<h2>Inadequate Solutions</h2>
<p>So how do people manage this?  I mean, beyond having the logic at the control level.</p>
<p>Well, you can put controls for different states on their own panel for their states.  So in the example above, you could add the buttons directly onto the wizard page control<a href="#_ftn5" name="_ftnref5">[5]</a>.  This would ensure the correct buttons, for the panel, are displayed, but it doesn’t solve the ‘Back’ button logic of which page to display.</p>
<p>Or you could add some kind of control grouping mechanism, like a collection of the controls, to display or hide all controls at once.  The problem with this, is what happens when you have functionality which will enable/disable a specific control, or do something else?  Do you add another grouping or another function to manipulate your control group, or do you have that one function do enabling/disabling as well?  What happens if the enabling/disabling logic is different from the display logic?  You also have the problem of one control being in multiple groups; will your groupings need to be called in the order of hide, then show, just to get the control that’s in both groups to display?  And if you do, will you let the control flicker? Or will you add extra functionality to prevent specific controls from hiding in the first place, so it won’t flicker?</p>
<p>Or maybe you can make a centralized function to manage the controls where the display is based on the passed in parameters.  Well this is very close, but no cigar.  Not only are the parameters needless, as I’ll show later, but this won’t completely remove logic from the events and can needlessly increase logic in that function.</p>
<p>The solution most have preferred is to make screens as minimal as possible, with a new screen for each piece of functionality.  This is often effective, at the cost of usability, but sometimes has its own problems like managing state while gathering data from multiple screens to persist it all in one shot.  Not even to mention that this strategy would be ineffective in our example.  Besides, in my experience, you can never really get away from at least some display manipulation.</p>
<p>This is a small example; imagine having a screen with 50 controls, where many of them change state.  Imagine how difficult it would be to manage the display this way.</p>
<p>Hopefully you can see how this can turn into a major pain in the butt.</p>
<p>Well, the good news is this problem has been solved …. Solved a long time ago actually<a href="#_ftn6" name="_ftnref6">[6]</a>.</p>
<p>The solution is ….</p>
<h2>The UpdateUI() Method</h2>
<p>It’s pretty simple really; just create a single function for the entire page, view, form, or screen (whatever it’s called in your technology).  All this function does, is manage the control display.  Then call this function at the end of every event, after all data manipulation.</p>
<p>It’s pretty simple; there are just …</p>
<h2>5 Rules for the UpdateUI() method</h2>
<p>1.     <strong>Fast</strong> – Don’t do anything which isn’t fast.  The state data driving the display decisions should already be calculated.</p>
<p>2.    <strong> No parameters</strong> – You should be able to make all decisions about display using the current screens state.</p>
<p>3.     <strong>No side effects</strong> – Don’t manipulate data within this method.  Not only can it slow it down, but it can also lead to inconsistent display evaluations.</p>
<p>4.     <strong>Manage each control individually</strong> &#8211; Don&#8217;t hide all controls, then show the controls you want displayed.  This causes flicker and adds unnecessary complexity.</p>
<p>5.     <strong>Call it last</strong> – call this function at the end of <em>every</em> event.</p>
<h2>Code Sample</h2>
<p>Here’s a little sample of what the wizard UpdateUI() code might look like.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> UpdateUI<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
 basicUserPg<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">BasicUserInfo</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 buyerPg<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">BuyerInfo</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 individualSellerPg<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">IndividualSellerInfo</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 commercialSellerPg<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CommercialSellerInfo</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 commercialSellerTaxPg<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CommercialSellerTaxInfo</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 reviewPg<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">Review</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 processingPg<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">Processing</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 compeletedPg<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CompletionStatusReport</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
 cancelButton<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">BasicUserInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">BuyerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">IndividualSellerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CommercialSellerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CommercialSellerTaxInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">Review</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 previousButton<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">BuyerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">IndividualSellerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CommercialSellerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CommercialSellerTaxInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">Review</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 nextButton<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">BasicUserInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">BuyerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">IndividualSellerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CommercialSellerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CommercialSellerTaxInfo</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 runButton<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">Review</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
 finishButton<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CompletionStatusReport</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>This is quite a bit simpler than having the code sprinkled throughout the screen’s logic.</p>
<p>You may also want to move many expressions into their own protected properties. For example, you may want to change …</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">cancelButton<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">BasicUserInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">BuyerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">IndividualSellerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CommercialSellerInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">CommercialSellerTaxInfo</span>
                     <span style="color: #008000;">||</span> CurrentPage <span style="color: #008000;">==</span> NewUserWizardPage<span style="color: #008000;">.</span><span style="color: #0000FF;">Review</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>… to …</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">cancelButton<span style="color: #008000;">.</span><span style="color: #0000FF;">Visible</span> <span style="color: #008000;">=</span> DisplayCancelButton<span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>Unfortunately, if your screen has a lot of controls, you may end up with a lot of these properties.  Because the state used to make the display decisions is usually in that screens class, it’s difficult to move these expressions into a separate class.  Or at least it is difficult to make a generalized statement about how to do it.</p>
<h2>Where to use</h2>
<p>This technique can be used in every GUI language or technology I’ve ever worked with.  I’ve used this strategy in Classic VB, C++ (MFC<a href="#_ftn7" name="_ftnref7">[7]</a>, Win32), Classic ASP, PHP, JavaScript, ASP.NET webforms<a href="#_ftn8" name="_ftnref8">[8]</a> , etc…</p>
<p>This technique can significantly reduce Ajax initiated display adjustments.</p>
<h2>Costs</h2>
<p>The cost to managing your display this way is a slight increase in computing power required to calculate every display decision on every event.  However, in reality, if your UpdateUI() function causes a performance issue that’s noticeable, you’ve probably missed one of the rules stated above.</p>
<p>In my opinion, the increased simplicity, and cleanliness of you code, more than makes up for the slight increase in processing.</p>
<h2>Conclusion</h2>
<p>The UpdateUI() method is an efficient and effective way to keep your display manipulation code clean &amp; bug free.  Even if your screen is relatively simple, you still benefit from having all your code in one place, and if it does grow in complexity, it will be manageable.  This technique has saved me countless hours of frustration.</p>
<p>Copyright © John MacIntyre 2010, All rights reserved </p>
<hr size="1" />
<p><a href="#_ftnref1" name="_ftn1">[1]</a> These examples are really difficult to come up with, so let’s just go with this.  In reality many screens will be much more complex as well.</p>
<p><a href="#_ftnref2" name="_ftn2">[2]</a> I don’t necessarily mean ‘code behind your buttons’, but any logic executed specifically for this button, as a result of clicking it.</p>
<p><a href="#_ftnref3" name="_ftn3">[3]</a> For proof, see my avatar.  <img src='http://whileicompile.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><a href="#_ftnref4" name="_ftn4">[4]</a> As if one place isn’t enough</p>
<p><a href="#_ftnref5" name="_ftn5">[5]</a> Wizard page controls <em>are</em> on their own panel of course, I mean we’ve all definitely learned that haven’t we?</p>
<p><a href="#_ftnref6" name="_ftn6">[6]</a> MFC had UpdateUI() as a virtual method on its main window class in the mid-1990s.  Fortunately, this was one of the only new paradigms Microsoft has ever added which did not undo the solution I came up with in the last paradigm</p>
<p><a href="#_ftnref7" name="_ftn7">[7]</a> The name actually comes from the CView::UpdateUI() method in MFC which was a core method for all UI related activity, before MFC I was calling it EnableCtrls().</p>
<p><a href="#_ftnref8" name="_ftn8">[8]</a> In ASP.NET WebForms, this function is called Page.PreRender.  However, this solution isn’t the greatest, since any control with an event needs to be populated in Page.OnInit just to wire up events properly.</p>
<p>Thanks to <a href="http://blog.syntaxc4.net/">Cory Fowler</a> for reviewing my post.</p>
]]></content:encoded>
			<wfw:commentRss>http://whileicompile.com/2010/10/the-ui-programmers-not-so-secret-weapon/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>My week (09/18/2010)</title>
		<link>http://whileicompile.com/2010/09/my-week-09182010/</link>
		<comments>http://whileicompile.com/2010/09/my-week-09182010/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 02:20:54 +0000</pubDate>
		<dc:creator>John MacIntyre</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://whileicompile.wordpress.com/?p=548</guid>
		<description><![CDATA[Blog Posts Earlier this week I posted What is too simpl [...]]]></description>
				<content:encoded><![CDATA[<p><strong>Blog Posts</strong></p>
<p>Earlier this week I posted <a href="http://whileicompile.wordpress.com/2010/09/14/what-is-too-simple-and-small-to-refactor-as-clean-code/">What is too simple and small to refactor?</a> about a  follow up to <a href="http://whileicompile.wordpress.com/2010/08/24/my-clean-code-experience-no-1/">my first Clean Code experience </a>where I took a very small function, and refactored it.  In the end I was truly questioning; how small is too small to refactor?  This post received quite a bit of a response, including <a href="http://thecleancoder.blogspot.com/2010/09/too-small-to-refactor.html">a response from Uncle Bob Martin</a> and several refactors from <a href="http://codingincaledon.wordpress.com/2010/09/16/clean-code-experience/">Cliff Mees</a>, <a href="http://randomcode.net.nz/">Neal Blomfield</a> (<a href="http://gist.github.com/581506">his response</a>), <a href="http://blog.syntaxc4.net/post/2010/09/14/Reply-What-is-too-simple-and-small-to-refactor.aspx">Cory Fowler</a>, <a href="http://www.endswithsaurus.com/2010/09/reply-what-is-too-simple-and-small-to.html"> Ben Alabaster begin_of_the_skype_highlighting     end_of_the_skype_highlighting</a>, and even <a href="http://msmvps.com/blogs/jon_skeet/archive/2010/09/15/reply-to-a-reply-tweaking-refactoring.aspx">Jon Skeet</a>.</p>
<p><strong>My Twitter Worth Mentioning(?)</strong></p>
<p>&#8220;..I&#8217;d explain why, but I have to, like, go put on lipstick.&#8221;-@<a rel="nofollow" href="http://twitter.com/aalear">aalear</a> responding to a comment &#8220;females are too busy being beautiful&#8221; <a title="#gogirl" rel="nofollow" href="http://twitter.com/search?q=%23gogirl">#gogirl</a> <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24617389515"> 8:25 PM Sep 15th</a></p>
<p>My recent blog posts have generated a lot of feedback among my friends &amp; colleagues. I&#8217;m glad. It&#8217;s a great conversation.                   <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24539789024"> 12:09 AM Sep 15th</a></p>
<p>I&#8217;m going to create a restaurant review site &amp; call it StickyTables.com                   <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24398683074"> 12:51 PM Sep 13th</a></p>
<p>&#8220;Clean Code is a design philosophy more than a naming convention.&#8221; &#8211; me <a title="#justQuotedMyself" rel="nofollow" href="http://twitter.com/search?q=%23justQuotedMyself">#justQuotedMyself</a> <a title="#dealWithIt" rel="nofollow" href="http://twitter.com/search?q=%23dealWithIt">#dealWithIt</a> <img src='http://whileicompile.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />                    <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24397491143"> 12:36 PM Sep 13th</a></p>
<p>If somebody says my code sucks &amp; they&#8217;ll redo it, I&#8217;d be hurt. But for my design, I&#8217;m relieved.  <a title="#mspaintSucks" rel="nofollow" href="http://twitter.com/search?q=%23mspaintSucks">#msPaintSucks</a> <img src='http://whileicompile.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />                    <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24389456504"> 10:56 AM Sep 13th</a></p>
<p>Just saw a really cool job title on LinkedIn &#8220;Experienced Code Poet&#8221;                   <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24347209407"> 11:04 PM Sep 12th</a></p>
<p>When I hear &#8220;the cloud&#8221; I know I no longer understand what the other person is talking about. <a title="#widelyMisusedTerm" rel="nofollow" href="http://twitter.com/search?q=%23widelyMisusedTerm">#widelyMisusedTerm</a> <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24339524259"> 9:58 PM Sep 12th</a></p>
<p>Friday; I love you, but you come way too fast. <a title="#in" rel="nofollow" href="http://twitter.com/search?q=%23in">#in</a> <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24748896981"> 7:12 AM Sep 17th</a></p>
<p>Even  when they score a major coup to attract &amp; add value to users, the  announcement is littered with comments like &#8220;Who uses @<a rel="nofollow" href="http://twitter.com/MySpace">MySpace</a>? &#8221;                   <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24672483679"> 11:16 AM Sep 16th</a></p>
<p>Got to say; one of the biggest challenges I have blogging is coming up /w relevant examples.                   <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24658476708"> 8:17 AM Sep 16th</a></p>
<p><a title="#FF" rel="nofollow" href="http://twitter.com/search?q=%23FF">#FF</a> @<a rel="nofollow" href="http://twitter.com/unclebobmartin">unclebobmartin</a> not for his Clean Code msg, which is awesome, but for addressing your questions &amp; concerns.  <a title="#wayToGo" rel="nofollow" href="http://twitter.com/search?q=%23wayToGo">#wayToGo</a> <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24786672710"> about 19 hours ago</a></p>
<p>A programmer  started to cuss Cause getting 2 sleep was a fuss As he lay there in bed  Looping round in his head Was while(!asleep()) sheep++;                <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/23964952377"> 9:13 PM Sep 8th</a> (this wasn&#8217;t mine, it was quoted from <a href="http://stackoverflow.com/questions/58640/great-programming-quotes/59003#59003">a StackOverflow question</a>)</p>
<p>In my opinion &#8216;no written requirements&#8217; is the biggest kiss of death a project can have.  <a title="#stackexchange" rel="nofollow" href="http://twitter.com/search?q=%23stackexchange">#stackexchange</a> <a rel="nofollow" href="http://bit.ly/d3rho2" target="_blank">http://bit.ly/d3rho2</a> <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/23950084933"> 5:42 PM Sep 8th</a></p>
<p>I don&#8217;t hate technical buzzwords, only the ones non-tech people have hijacked.                <a rel="bookmark" href="http://twitter.com/JohnMacIntyre/status/24694144939"> 4:17 PM Sep 16th</a></p>
<p><strong>Wisdom from Twitter</strong></p>
<p><a href="http://twitter.com/utahkay"><img src="http://a2.twimg.com/profile_images/334908530/kay_normal.JPG" alt="utahkay" width="48" height="48" /></a> <strong>@<a href="http://twitter.com/utahkay">utahkay </a></strong>We&#8217;ve outsourced your project to a colony of bacteria. Not the best programmers, but you can get a lot of them for cheap.                <a rel="bookmark" href="http://twitter.com/utahkay/status/22386731336"> 6:08 PM Aug 28th</a></p>
<p><a href="http://twitter.com/datachick"><img src="http://a3.twimg.com/profile_images/644124575/karenavatar150-oct2008_normal.png" alt="Karen Lopez" width="48" height="48" /></a> @<strong><a href="http://twitter.com/datachick">datachick </a></strong>&#8220;repay technical debt as soon as possible&#8221; @<a rel="nofollow" href="http://twitter.com/drsql">drsql</a> <a title="#24HOP" rel="nofollow" href="http://twitter.com/search?q=%2324HOP">#24HOP</a> <a title="#DarcVC" rel="nofollow" href="http://twitter.com/search?q=%23DarcVC">#DarcVC</a> <a rel="bookmark" href="http://twitter.com/datachick/status/24702269733">6:19 PM Sep 16th</a></p>
<p><a href="http://twitter.com/justicegray"><img src="http://a1.twimg.com/profile_images/1104463353/justice_aug2010clipped_normal.jpg" alt="Justice Gray" width="48" height="48" /></a> <strong><a href="http://twitter.com/justicegray">@justicegray </a></strong>I have a dream that one day it  will take more to be an &#8220;industry expert&#8221; in software development than  just calling yourself one publicly.                <a rel="bookmark" href="http://twitter.com/justicegray/status/24523798902"> 8:37 PM Sep 14th</a></p>
<p><a href="http://twitter.com/BenAlabaster"><img src="http://a1.twimg.com/profile_images/646919689/Avatar_normal.jpg" alt="Ben Alabaster" width="48" height="48" /></a> @<strong><a href="http://twitter.com/BenAlabaster">BenAlabaster </a></strong>You had me at &#8220;Hello World!&#8221; <a title="#ProgrammerPickupLines" rel="nofollow" href="http://twitter.com/search?q=%23ProgrammerPickupLines">#ProgrammerPickupLines</a> <a rel="bookmark" href="http://twitter.com/BenAlabaster/status/24801606755"> 7:40 PM Sep 17th</a></p>
<p><a href="http://twitter.com/wrox"><img src="http://a1.twimg.com/profile_images/704319049/13_0470502258_normal.jpg" alt="Jim Minatel" width="48" height="48" /></a> @<strong><a href="http://twitter.com/wrox">wrox</a></strong> Stupid password policies just make people use stupid passwords                <a rel="bookmark" href="http://twitter.com/wrox/status/24770608495"> 12:01 PM Sep 17th</a></p>
<p><a href="http://twitter.com/MichaelKramer"><img src="http://a3.twimg.com/profile_images/345039547/profile_normal.jpg" alt="Michael Kramer" width="48" height="48" /></a> <strong><a href="http://twitter.com/MichaelKramer">@MichaelKramer</a></strong> Sorry IE9, I can&#8217;t use you. I&#8217;m still too pissed about IE6.                <a rel="bookmark" href="http://twitter.com/MichaelKramer/status/24599770228"> 4:08 PM Sep 15th</a></p>
<p><a href="http://twitter.com/carlosfigueroa"><img src="http://a0.twimg.com/profile_images/727743860/twitterProfilePhoto_normal.jpg" alt="Carlos Figueroa" width="48" height="48" /></a> @<strong><a href="http://twitter.com/carlosfigueroa">carlosfigueroa</a></strong> If you can&#8217;t be replaced, you probably can&#8217;t be promoted.                <a rel="bookmark" href="http://twitter.com/carlosfigueroa/status/24026805133"> 12:56 PM Sep 9th</a></p>
<p><a href="http://twitter.com/cammerman"><img src="http://a0.twimg.com/profile_images/809935872/twitter_avatar_normal.jpg" alt="Chris Ammerman" width="48" height="48" /></a> @<strong><a href="http://twitter.com/cammerman">cammerman</a></strong> Everyone thinks their opinions are rational, but often they&#8217;re merely rationalized.                <a rel="bookmark" href="http://twitter.com/cammerman/status/24017588743"> 11:07 AM Sep 9th</a></p>
<p><a href="http://twitter.com/KentBeck"><img src="http://a1.twimg.com/profile_images/210066337/kentbeck_normal.png" alt="Kent Beck" width="48" height="48" /></a> @<strong><a href="http://twitter.com/KentBeck">KentBeck</a></strong> if you don&#8217;t have a good name for it, give it a bad name. a really, really bad name so you&#8217;ll fix it later.                <a rel="bookmark" href="http://twitter.com/KentBeck/status/23957880068"> 7:31 PM Sep 8th</a></p>
<p><a href="http://twitter.com/_KYA"><img src="http://a0.twimg.com/profile_images/825453348/new_ava_normal.jpg" alt="Knowles Atchison Jr" width="48" height="48" /></a> <strong><a href="http://twitter.com/_KYA">@_KYA</a> </strong>&#8220;The beauty of the Internet is  you can just pull a quote out of your ass and attribute it to whoever  the fuck you want.&#8221; &#8211; George Washington                <a rel="bookmark" href="http://twitter.com/_KYA/status/23865858999"> 8:19 PM Sep 7th</a></p>
<p><strong>Recommended links found this week</strong></p>
<p><a href="http://joshduck.com/periodic-table.html">Periodic Table of the Elements</a> (via <a href="http://www.johndcook.com/blog/">John D Cook</a>)</p>
<p><a href="http://www.albahari.com/threading/">Threading in C#</a></p>
<p><a href="http://randomcode.net.nz/2009/12/10/why-software-development-metaphors-always-fail/">Why software development metaphors always fail</a></p>
<p><a href="http://blog.typemock.com/2010/03/finally-entire-interview-with-uncle-bob.html">Finally The Entire Interview with Uncle Bob Martin</a></p>
<p><a href="http://www.khanacademy.org/">Khan Academy</a></p>
<p><a href="http://michaelcrump.net/archive/2010/05/25/tools-and-utilities-for-the-.net-developer.aspx">Tools and Utilities for the .NET Developer</a></p>
<p><strong>Videos this week</strong></p>
<p>This one is freakin hilarious.  Here&#8217;s a quote &#8220;Does /dev/null/ support sharding?&#8221;  <a href="http://highscalability.com/blog/2010/9/5/hilarious-video-relational-database-vs-nosql-fanbois.html">Mongo DB is web scale</a> Unfortunately, I can&#8217;t embed it.  Here&#8217;s the sequel <a href="http://www.xtranormal.com/watch/7023615/">Episode 2 &#8211; All The Cool Kids Use Ruby</a>.  I also saw <a href="http://nosql.mypopescu.com/post/1085685966/mysql-is-not-acid-compliant">MySQL is Not ACID Compliant</a>, which is basically the same as Mongo DB is Web Scale, but about MySQL.</p>
<p>Here&#8217;s a great quote from the following video:  &#8220;How many languages to you have to know to get a god damn web page up?&#8221; &#8211; @<a rel="nofollow" href="http://twitter.com/unclebobmartin">unclebobmartin</a><br />
[youtube=http://www.youtube.com/watch?v=mslMLp5bQD0&amp;fs=1&amp;hl=en_US]<br />
[youtube=http://www.youtube.com/watch?v=4F72VULWFvc&amp;fs=1&amp;hl=en_US] </p>
]]></content:encoded>
			<wfw:commentRss>http://whileicompile.com/2010/09/my-week-09182010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What is too simple and small to refactor? (Clean Code Experience No. 2)</title>
		<link>http://whileicompile.com/2010/09/what-is-too-simple-and-small-to-refactor-as-clean-code/</link>
		<comments>http://whileicompile.com/2010/09/what-is-too-simple-and-small-to-refactor-as-clean-code/#comments</comments>
		<pubDate>Tue, 14 Sep 2010 12:36:15 +0000</pubDate>
		<dc:creator>John MacIntyre</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Clean-Code]]></category>

		<guid isPermaLink="false">http://whileicompile.wordpress.com/?p=521</guid>
		<description><![CDATA[Shortly after reading Clean Code, I refactored the data access layer from a project I was working on, and was amazed by how much the code improved.  It really was night and day.  My first clean code refactoring experience was an obvious improvement. 

I was still on that clean code high, when a little function entered my life that I was compelled to refactor.  This one left me questioning the limits of what I should refactor and if my refactor even qualified as clean.  

I’d like to share that second experience with you in this post.]]></description>
				<content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p>Shortly after reading <a href="http://objectmentor.com/omTeam/martin_r.html">Robert C Martin</a>&#8216;s <a href="http://blog.objectmentor.com/articles/2008/04/08/clean-code-whew">Clean Code</a>, I refactored the data access layer from a project I was working on, and was amazed by how much the code improved.  It really was night and day.  <a href="http://whileicompile.wordpress.com/2010/08/24/my-clean-code-experience-no-1/">My first clean code refactoring experience</a> was an obvious improvement. </p>
<p>I was still on that clean code high, when a little function entered my life that I was compelled to refactor.  This one left me questioning the limits of what I should refactor and if my refactor even qualified as clean.</p>
<p>I’d like to share that second experience with you in this post.</p>
<p><strong>Original Code</strong></p>
<p>Here is the original code.  The code was written by and owned by <a href="http://frazzleddad.blogspot.com/">Jim Holmes</a>.  Jim was kind enough to give me permission to use it in this post, as I was unable to find an equivalent example.  Thanks Jim.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">float</span> WageCalculator<span style="color: #008000;">&#40;</span> <span style="color: #6666cc; font-weight: bold;">float</span> hours,
                                    <span style="color: #6666cc; font-weight: bold;">float</span> rate,
                                    <span style="color: #6666cc; font-weight: bold;">bool</span> isHourlyWorker<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>hours <span style="color: #008000;">&amp;</span>lt<span style="color: #008000;">;</span> <span style="color: #FF0000;">0</span> <span style="color: #008000;">||</span> hours <span style="color: #008000;">&amp;</span>gt<span style="color: #008000;">;</span> <span style="color: #FF0000;">80</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> ArgumentException<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #6666cc; font-weight: bold;">float</span> wages <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>hours <span style="color: #008000;">&amp;</span>gt<span style="color: #008000;">;</span> <span style="color: #FF0000;">40</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">var</span> overTimeHours <span style="color: #008000;">=</span> hours <span style="color: #008000;">-</span> <span style="color: #FF0000;">40</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>isHourlyWorker<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            wages <span style="color: #008000;">+=</span> <span style="color: #008000;">&#40;</span>overTimeHours <span style="color: #008000;">*</span> 1<span style="color: #008000;">.</span>5f<span style="color: #008000;">&#41;</span> <span style="color: #008000;">*</span> rate<span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">else</span>
        <span style="color: #008000;">&#123;</span>
            wages <span style="color: #008000;">+=</span> overTimeHours <span style="color: #008000;">*</span> rate<span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
        hours <span style="color: #008000;">-=</span> overTimeHours<span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
    wages <span style="color: #008000;">+=</span> hours <span style="color: #008000;">*</span> rate<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">return</span> wages<span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>So as you can see, this simple method calculates a workers weekly pay based on hours worked, their hourly rate, and if they receive overtime or straight pay.  There really isn’t much to it, is there?</p>
<p>So why was I compelled to refactor such a simple piece of code?</p>
<p>As soon as I opened this function, I felt it was doing too much.  Mostly it was the <em>isHourlyWorker</em> parameter.</p>
<p>Since reading Clean Code, I’ve come to realize<em> boolean and enum parameter types are a huge tell that they should be refactored into separate classes</em>.*</p>
<p><strong>My refactored code</strong></p>
<p>So what did my refactored code look like after spending 30 minutes or so playing with it?</p>
<p>Well, here’s the new class diagram first, so you get some idea what you’re looking at.<br />
<a href="http://whileicompile.com/wp-content/uploads/2010/09/cleancoderefactorno21.png"><img src="http://whileicompile.com/wp-content/uploads/2010/09/cleancoderefactorno21.png" alt="Class diagram of refactor results" title="Class diagram of refactor results" width="571" height="476" class="aligncenter size-full wp-image-533" /></a></p>
<p>And here’s the code</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">abstract</span> <span style="color: #6666cc; font-weight: bold;">class</span> WageCalculatorBase
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">float</span> HoursWorked <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">get</span><span style="color: #008000;">;</span> <span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">set</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">float</span> HourlyRate <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">get</span><span style="color: #008000;">;</span> <span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">set</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> WageCalculatorBase<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">float</span> hours, <span style="color: #6666cc; font-weight: bold;">float</span> hourlyRate<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>hours <span style="color: #008000;">&amp;</span>lt<span style="color: #008000;">;</span> <span style="color: #FF0000;">0</span> <span style="color: #008000;">||</span> hours <span style="color: #008000;">&amp;</span>gt<span style="color: #008000;">;</span> <span style="color: #FF0000;">80</span><span style="color: #008000;">&#41;</span>
            <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> ArgumentOutOfRangeException<span style="color: #008000;">&#40;</span><span style="color: #008000;">&amp;</span>quot<span style="color: #008000;">;</span>Hours must be between <span style="color: #FF0000;">0</span> and <span style="color: #FF0000;">80</span><span style="color: #008000;">.&amp;</span>quot<span style="color: #008000;">;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        HoursWorked <span style="color: #008000;">=</span> hours<span style="color: #008000;">;</span>
        HourlyRate <span style="color: #008000;">=</span> hourlyRate<span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">abstract</span> <span style="color: #6666cc; font-weight: bold;">float</span> Calculate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> WageCalculatorForEmployee <span style="color: #008000;">:</span> WageCalculatorBase
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> WageCalculatorForEmployee<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">float</span> hours, <span style="color: #6666cc; font-weight: bold;">float</span> hourlyRate<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">:</span> <span style="color: #0600FF; font-weight: bold;">base</span><span style="color: #008000;">&#40;</span>hours, hourlyRate<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #6666cc; font-weight: bold;">float</span> Calculate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>IsOvertimeRequired<span style="color: #008000;">&#41;</span>
            <span style="color: #0600FF; font-weight: bold;">return</span> CalculateWithOvertime<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> CalculateWithoutOvertime<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #6666cc; font-weight: bold;">bool</span> IsOvertimeRequired
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">get</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0600FF; font-weight: bold;">return</span> HoursWorked <span style="color: #008000;">&amp;</span>gt<span style="color: #008000;">;</span> <span style="color: #FF0000;">40</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #6666cc; font-weight: bold;">float</span> CalculateWithoutOvertime<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> HoursWorked <span style="color: #008000;">*</span> HourlyRate<span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #6666cc; font-weight: bold;">float</span> CalculateWithOvertime<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #6666cc; font-weight: bold;">float</span> overTimeHours <span style="color: #008000;">=</span> HoursWorked <span style="color: #008000;">-</span> <span style="color: #FF0000;">40</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span>overTimeHours <span style="color: #008000;">*</span> 1<span style="color: #008000;">.</span>5f <span style="color: #008000;">+</span> <span style="color: #FF0000;">40</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">*</span> HourlyRate<span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">float</span> Calculate<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">float</span> hours, <span style="color: #6666cc; font-weight: bold;">float</span> hourlyRate<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        WageCalculatorForEmployee payCalc <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WageCalculatorForEmployee<span style="color: #008000;">&#40;</span>hours, hourlyRate<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> payCalc<span style="color: #008000;">.</span><span style="color: #0000FF;">Calculate</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> WageCalculatorForContractor <span style="color: #008000;">:</span> WageCalculatorBase
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> WageCalculatorForContractor<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">float</span> hours, <span style="color: #6666cc; font-weight: bold;">float</span> hourlyRate<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">:</span> <span style="color: #0600FF; font-weight: bold;">base</span><span style="color: #008000;">&#40;</span>hours, hourlyRate<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #6666cc; font-weight: bold;">float</span> Calculate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> HoursWorked <span style="color: #008000;">*</span> HourlyRate<span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">float</span> Calculate<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">float</span> hours, <span style="color: #6666cc; font-weight: bold;">float</span> hourlyRate<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        WageCalculatorForContractor payCalc <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WageCalculatorForContractor<span style="color: #008000;">&#40;</span>hours, hourlyRate<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> payCalc<span style="color: #008000;">.</span><span style="color: #0000FF;">Calculate</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>And the code to execute this would be as simple as</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">weeklyPay <span style="color: #008000;">=</span> WageCalculatorForEmployee<span style="color: #008000;">.</span><span style="color: #0000FF;">Calculate</span><span style="color: #008000;">&#40;</span>hoursWorked, hourlyRate<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p> or</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">weeklyPay <span style="color: #008000;">=</span> WageCalculatorForContractor<span style="color: #008000;">.</span><span style="color: #0000FF;">Calculate</span><span style="color: #008000;">&#40;</span>hoursWorked, hourlyRate<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>Or as flexible as</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">WageCalculatorBase wageCalculator <span style="color: #008000;">=</span> WageCalculatorFactory<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">Get</span><span style="color: #008000;">&#40;</span>employeeInfo, hoursWorked, hourlyRate<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
weeklyPay <span style="color: #008000;">=</span> wageCalculator<span style="color: #008000;">.</span><span style="color: #0000FF;">Calculate</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>So as I said earlier, it was the <em>isHourlyWorker</em> parameter which compelled me to refactor.  Notice how this parameter no longer exists, and has been replaced by a class for each of the potential values.  <em>isHourlyWorker</em> has become the <em>WageCalculatorForEmployee</em> class, and <em><strong>!</strong>isHourlyWorker</em> has become the <em>WageCalculatorForContractor</em> class.</p>
<p>Now one of the first questions you may have about the refactor is why didn’t I implement the <em>Calculate</em> method in the <em>WageCalculatorBase</em> class, instead of declaring it as abstract?  Especially since both derived classes have identical methods, namely the <em>CalculateWithoutOvertime</em> method in the <em>WageCalculatorForEmployee</em> class, and the <em>Calculate</em> method in the <em>WageCalculatorForContractor</em> class.</p>
<p>What the hell happened to DRY?</p>
<p>I considered doing that, but decided that the <em>Calculate</em> method is such an important and critical piece of functionality, that implementation should not be left to chance. I felt an <em>explicit</em> implementation should be required.</p>
<p>And while we’re on the topic of the <em>CalculateWithoutOvertime()</em> method, you may be asking yourself, why this method even exists?  I mean couldn’t<em> CalculateWithoutOvertime()</em>, <em>CalculateWithOvertime()</em>, and the <em>IsOvertimeRequired</em> property have been easily implemented in the <em>Calculate()</em> method?</p>
<p>Yes, as a matter of fact, I could have done it in a single expression, but felt it might be complex enough to warrant a comment, so I added the commenting into the structure, and kept the complexity way down.</p>
<p><strong>Observations</strong></p>
<p>Something else you may notice is the lack of control statements and flow branching.  Notice, there are barely any ‘if’s.  You may also notice the methods are very small, with the longest method being only 4 LOC, and most are 2.</p>
<p>You may also notice the increase in structural complexity, as noticed in Clean Code Experience #1.</p>
<p>But the real kicker to this refactor is that the original 26 lines of code became 74 when the refactoring was completed (including whitespace and everything).  That’s a near 300% LOC increase!  </p>
<p>This r-e-a-l-l-y bothered me, and left me perplexed as to if my refactor was foolish or wise.</p>
<p><strong>Good idea?</strong></p>
<p>So was it a good idea to refactor it?  Is this clean code? Or was I just over stimulating myself with the refactoring?  Was I partaking in refactoring masturbation?</p>
<p>I mean really … this wasn’t a complex function.  There was nothing wrong with the function and the amount of code actually increased.</p>
<p>It took me a long time to wrap my head around this, but I finally decided this was good code.  This was clean code.  This was appropriate if creating code from scratch.  This might be appropriate if working on client code.</p>
<p>.. Wait! .. what?</p>
<p>What do I mean, <em>might</em> be appropriate?</p>
<p><strong>Would I do it in real life?</strong></p>
<p>There is an ROI on business software.  Unfortunately, software is not merely our art and our craft.  Software is an investment.  Software is a financial investment.  More specifically, it’s not even our financial investment, it’s our employers.</p>
<p>So should you spend 30 minutes refactoring the above code?  Is there an ROI worth it?<br />
As much as I want to do that refactor, and believe later maintenance will benefit from it, I seriously question if the ROI would warrant it.  I don&#8217;t think I would refactor this on its own.</p>
<p>…. Unless I was working on that code as part of my current task.  If I’m already working on that code, then yes, by all means, it’s appropriate.  It’s appropriate as part of my current task and as an act of craftsmanship to leave the code cleaner than I found it.</p>
<p>If it was my project, would I do it?  </p>
<p>Yes, without a doubt I would.  But that’s because I see software that I write for myself as more of a vehicle of artistic expression than a financial investment.**</p>
<p><strong>What do you think?</strong></p>
<p>I’d be interested in hearing your thoughts.</p>
<p>Is this clean code?  </p>
<p>Is this good design?  </p>
<p>Should you refactor code that is this small?  </p>
<p>When should you refactor something like this?  </p>
<p>What are the guidelines as to when it’s worth it to refactor or not?</p>
<p><em>* I don’t remember if he said this in the book or if this was my own insight.  I don’t’ even know if Uncle Bob would agree with that statement</em><br />
<em>** My inability to view my own software as a financial investment is also the reason I’ve never released anything awesome and made a ton of money.</em></p>
<p>Copyright © John MacIntyre 2010, All rights reserved </p>
]]></content:encoded>
			<wfw:commentRss>http://whileicompile.com/2010/09/what-is-too-simple-and-small-to-refactor-as-clean-code/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
