<?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>NOthingyoumissed &#187; Programming</title>
	<atom:link href="http://georgemauer.net/blog/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://georgemauer.net/blog</link>
	<description>George Mauer is on the net</description>
	<lastBuildDate>Sat, 15 May 2010 16:13:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Online Collaboration Tools List</title>
		<link>http://georgemauer.net/blog/online-collaboration-tools-list/</link>
		<comments>http://georgemauer.net/blog/online-collaboration-tools-list/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 06:26:11 +0000</pubDate>
		<dc:creator>togakangaroo</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://georgemauer.net/blog/?p=167</guid>
		<description><![CDATA[I do a lot of online collaboration.  So here is my list of online collaboration tools that I like to use.

Jing &#8211; The absolutely best way to capture screenshots and video, upload and share it immediately
Charting

Yuml.me &#8211; Insanely awesome tool for UML diagrams
Websequencediagrams.com &#8211; Insanely awesome tool for sequence diagrams


Dabbleboard &#8211; Great online whiteboarding [...]]]></description>
			<content:encoded><![CDATA[<p>I do a lot of online collaboration.  So here is my list of online collaboration tools that I like to use.</p>
<ul>
<li>Jing &#8211; The absolutely best way to capture screenshots and video, upload and share it immediately</li>
<li>Charting
<ul>
<li>Yuml.me &#8211; Insanely awesome tool for UML diagrams</li>
<li>Websequencediagrams.com &#8211; Insanely awesome tool for sequence diagrams</li>
</ul>
</li>
<li>Dabbleboard &#8211; Great online whiteboarding utility</li>
<li>Mockups
<ul>
<li>Balsamiq &#8211; Incredible quick mockup builder</li>
<li>Moquingbird &#8211; Similar to Balsamiq but with different strengths.  I think its better for capturing screenflows</li>
</ul>
</li>
<li>Online meeting
<ul>
<li>Webex &#8211; The best (I used it to screenshare and do live meetings with India) but prohibitively  expensive</li>
<li>Microsoft Livemeeting</li>
<li>GotoMetting</li>
<li>Dimdim</li>
</ul>
</li>
<li>Bubbl.us &#8211; A really promising mindmapping tool</li>
<li>Trac &#8211; Simple integrated wiki/issue tracker and svn.  I just really like this wiki for its simplicity and I&#8217;ve used it in the past to great effect</li>
<li>Google groups &#8211; Make a private group for your project and have everyone sign up.  Now you have an effective mailing list which gives you threaded conversations and an online-accessible and fully searchable repository.  A big plus is that this is achieved with the communication lowest-common-denominator &#8211; email </li>
<li>Google Wave &#8211; I&#8217;m not convinced that this is ready for prime-time yet but it has some promise</li>
<li>Google Docs &#8211; Great for getting a survey, spreadsheet, anything Q&#038;A up and running super-quick.  Also online collaboration with documents and having an web-accessible powerpoint is great</li>
<li>Dropbox &#8211; Perfect for file sharing</li>
</ul>
<p>Plus <a href="http://sixrevisions.com/tools/15-free-tools-for-web-based-collaboration/">this site</a> has some great ideas.</p>
<p>I am going to add to this post as I encounter more tools that I find useful. </p>
]]></content:encoded>
			<wfw:commentRss>http://georgemauer.net/blog/online-collaboration-tools-list/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>My List of Tools I Cannot Live Without</title>
		<link>http://georgemauer.net/blog/my-list-of-tools-i-cannot-live-without/</link>
		<comments>http://georgemauer.net/blog/my-list-of-tools-i-cannot-live-without/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 19:47:06 +0000</pubDate>
		<dc:creator>togakangaroo</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://georgemauer.net/blog/?p=148</guid>
		<description><![CDATA[This one goes out to&#8230;me.  I&#8217;ve recently spent a lot of time setting up new workstations and am soon going to be spending a lot more.  This post is a rundown of all the tools and litter helper apps that I absolutely positively cannot live without.  Are there some gems in here [...]]]></description>
			<content:encoded><![CDATA[<p>This one goes out to&#8230;me.  I&#8217;ve recently spent a lot of time setting up new workstations and am soon <a href="http://georgemauer.net/blog/new-job-im-the-man/">going to be spending a lot more</a>.  This post is a rundown of all the tools and litter helper apps that I absolutely positively cannot live without.  Are there some gems in here that you would like?  Probably.  But mostly this one is for my own sake.</p>
<ul>
<li><a href="www.launchy.net/">Launchy </a>- Simple, fast, open source application launcher
<ul>
<li>Launchy Plugin &#8211; <a href="http://kozmic.pl/archive/2009/07/19/twitt.poster-reinvented-ndash-introducing-ty-twitter-for-launchy.aspx">Ty</a> to post to twitter from Krzysztof Ko?mic</li>
<li>Launchy Plugin &#8211; <a href="http://sourceforge.net/projects/launchy/forums/forum/677087/topic/1822422">GCaly</a> to post to your Google Calendar</li>
</ul>
</li>
<li><a href="http://bluemars.org/clipx/">ClipX </a>- Tiny little clipboard history manager.  I use this one about 70 times each day</li>
<li><a href="www.winsplit-revolution.com/">WinSplit Revolution</a> &#8211; Awesome utility to throw applications between dual monitors and tile them easily</li>
<li><a href="http://users.forthnet.gr/pat/efotinis/programs/deskpins.html">Deskpins </a>- A simple utility to force windows to stay on top.  Not the love of my life, but the best that I&#8217;ve found since xNeat went for-pay</li>
<li><a href="http://www.mozilla.com/firefox/">Firefox </a>- With the <a href="http://getfirebug.com/">firebug </a>and <a href="https://addons.mozilla.org/en-US/firefox/addon/60">Web Developer</a> plugins.  I really only use it for debugging pages and playing with javascript.  This is mostly because I use</li>
<li><a href="http://www.google.com/chrome">Chrome </a>- Web browser.  It just <em>feels</em> faster, ok?  Oh and the <a href="https://chrome.google.com/extensions/detail/amigcgbheognjmfkaieeeadojiibgbdp">too many tabs extension</a>.</li>
<li><a href="http://www.editpadpro.com/">EditPad Pro</a> &#8211; Great notepad utility.  Has an unlimited trial version, and I&#8217;ve had a license for it for years.  I might give Notepad2 a try, but I doubt I&#8217;ll make the jump.</li>
<li><a href="http://www.jzip.com/">jZip </a>- Open source zip utility.  Handles all the stuff that Winzip and WinRar do with less whining.</li>
<li><a href="http://tortoisesvn.tigris.org/">TortoiseSVN </a>- Windows Explorer &#8211; Integrated SVN source control.  As I use git more and more for personal projects I&#8217;m starting to regret how heavyweight the integration is though, might try something new next time.</li>
<li><a href="http://code.google.com/p/msysgit/downloads/list">MSysGit </a>- While we&#8217;re on the subject.</li>
<li><a href="http://www.fiddlertool.com/">Fiddler2 </a>- Http viewer, debugger. Don&#8217;t use it too much but its handy to have around.</li>
<li><a href="http://www.microsoft.com/downloads/details.aspx?familyid=e59c3964-672d-4511-bb3e-2d5e1db91038&#038;displaylang=en">IE 8 Developer Toolbar</a> &#8211; Its actually quite good</li>
<li><a href="http://www.gimp.org/">GIMP </a>- I ain&#8217;t a fancy-nancy designer and I&#8217;m not paying for Photoshop.</li>
<li><a href="http://www.getpaint.net/">Paint.NET</a> &#8211; When I want to draw stuff but don&#8217;t want something as heavyweight as GIMP</li>
<li><a href="www.inkscape.org/">Inkscape </a>- For working with svg images.  I use it surprisingly often</li>
<li><a href="http://winmerge.org/">WinMerge </a>- Great little application for comparing two files/directories/whatever</li>
<li><a href="http://sourceforge.net/projects/console/files/console-devel/2.00/Console-2.00b145-Beta_src.zip/download">Console2 </a>- Could never really get it to work better than the powershell default but it deserves another shot</li>
<li><a href="http://technet.microsoft.com/en-us/scriptcenter/dd772288.aspx">Powershell</a> &#8211; Are you a developer on windows and don&#8217;t use this?  You need to be punched in the face (or at least have you mouse stole).</li>
<li><a href="http://www.autohotkey.com/download">AutoHotKey</a> &#8211; For scripting windows
<ul>
<li>AutoHotKey Script &#8211; <a href="http://blog.jpboodhoo.com/BDDAutoHotKeyScriptUpdateTake2.aspx">BDD names</a> from JP Boodoohoo.  I had made some customizations to it but they were lost with the lastdisk crash.  Oh well</li>
</ul>
</li>
<li><a href="www.gallio.org/">Gallio Icarus</a> &#8211; Sometimes you just want a stand-alone test runner GUI and this is the best</li>
<li><a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">Putty </a>- For SSHing</li>
<li>TweakUI &#8211; For Windows XP.  Hopefully that&#8217;s a game I won&#8217;t have to play for much longer</li>
<li><a href="http://www.red-gate.com/products/reflector/">Reflector </a>- Must have for .NET development</li>
<li><a href="http://www.jingproject.com/">Jing </a>- Oh I love this.  The <em>best</em> for quick screen captures (though it would be nice if it had a lighter memoery footprint).</li>
<li><a href="filezilla-project.org/download.php">FileZilla Client</a> &#8211; Ftp I usually do with windows explorer (you knew it could do that, right?) but SFTP we need to bring in the pros</li>
<li>Ruby &#8211; I&#8217;m going to try just running IronRuby next time, I swear.</li>
<li>SQLite.NET &#8211; Tends to come up sooner or later, good for quick free file-based database</li>
<li>KeePass &#8211; I keep all my passwords in here &#8211; shh don&#8217;t tell anybody</li>
<li>Growl for Windows &#8211; I wrote a friggin&#8217; log4net Growl Appender, obviously I want something to read it.</li>
<li>Synergy &#8211; To share mouse and keyboard with multiple computers</li>
<li>Visual Studio &#8211; duh, but also the following plugins/extensions
<ul>
<li>TestDriven.NET &#8211; can&#8217;t live without youuuuu</li>
<li>T4 Toolbox &#8211; gotta have it since I like Sharp Architecture so much</li>
<li>ASP MVC &#8211; nuff said</li>
<li>ZenCoding &#8211; I haven&#8217;t had a chance to use it yet but I really can&#8217;t wait till I do</li>
<li>Refactor Pro and CodeRush &#8211; It&#8217;s a love affair, though I just picked up a ReSharper license at the last VAN so I guess I should compare and contrast or something
<ul>
<li>CR_ClassCleaner Plugin for DxCore</li>
</ul>
</li>
</ul>
</li>
<li><a href="http://office.microsoft.com/en-us/livemeeting/default.aspx">Microsoft Live Meeting</a> &#8211; For the virtual alt net sessions</li>
<li><a href="http://www.skype.com/">Skype</a></li>
<li><a href="https://www.dropbox.com/">Dropbox</a></li>
<li><a href="http://www.icsharpcode.net/OpenSource/SD/Download/">SharpDevelop </a>- I got to get into using this interesting IDE more</li>
<li>RubyMine &#8211; Great for ruby, and I have a license!</li>
<li><a href="www.videolan.org/">VLC Media Player</a> &#8211; Way more lightweight feeling than the others and plays anything</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://georgemauer.net/blog/my-list-of-tools-i-cannot-live-without/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hey, I Think I&#8217;ve Invented a New Pattern</title>
		<link>http://georgemauer.net/blog/hey-i-think-ive-invented-a-new-pattern/</link>
		<comments>http://georgemauer.net/blog/hey-i-think-ive-invented-a-new-pattern/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 07:58:12 +0000</pubDate>
		<dc:creator>togakangaroo</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[patterns]]></category>

		<guid isPermaLink="false">http://georgemauer.net/blog/?p=119</guid>
		<description><![CDATA[Ok maybe not totally new, I am sure that its just a projection of something I once noticed subcionscioiusly in a F# project. But in the C# space, I&#8217;ve yet to see something quite like it.  
The problem is that programs are complicated.  I don&#8217;t tend to help the issue.  In a [...]]]></description>
			<content:encoded><![CDATA[<p>Ok maybe not totally new, I am sure that its just a projection of something I once noticed subcionscioiusly in a F# project. But in the C# space, I&#8217;ve yet to see something quite like it.  </p>
<p>The problem is that programs are complicated.  I don&#8217;t tend to help the issue.  In a flash I don&#8217;t hesitate to layer on additional complexity with domain models, frameworks, and complex infrastructures.  Entities, sevices, repositories and aggregate roots &#8211; they&#8217;re the tools that we reach for all too often.  That is not to say that Domain Driven Design is a poor paradigm &#8211; I&#8217;m a big fan &#8211; it&#8217;s just not always necessary.</p>
<p>Take for example a typical scenario. You are given an integer which uniquely identifies a customer and are asked to generate a report of all their orders, export it to a pdf file and return as a Stream.  My first impulse is to start with the customer and order objects, identify the bounded context, figure out the aggregate roots, start writing data access mapping code, and so on.  If I&#8217;m lucky, I only do this for a few hours before hearing the voice of an incorporeal Ted Neward yelling at me to <strong>STOP</strong>.  I was not asked to build a domain model, I do not need to keep track of state, there is no validation, or (much) business logic.  The problems that DDD is intended to solve are simply not present here.  I need to do one thing and one thing only, map an integer to a Stream!  </p>
<p>And yes, I do realize that this is exactly what the CQRS guys have been harping on for years.</p>
<p>My Solution:</p>
<p>Each of my last few projects has contained a very simple interface.</p>
<pre name="code" class="c-sharp">
public IMapper&lt;INPUT_TYPE, OUTPUT_TYPE&gt; {
  OUTPUT_TYPE Map(INPUT_TYPE obj);
}
</pre>
<p>Get it? Put in an integer, get back a Stream, what could be simpler?  Ok, maybe that&#8217;s too simple.  Any change at all would require modifying the implementation.  This is all that icky procedural programming stuff.  What about reusability, encapsulation, separation of concerns, and our other OO goodies?   Fortunately, we don&#8217;t have to give these up.  All we have to do is introduce a couple of obvious seams.  We no longer transform an integer directly to a Stream.  Instead we:</p>
<ol>
<li>Take the id and map it to a DataSet that contains the report data.</li>
<li>Map a DataSet to the appropriate fully built Crystal Reports ReportDocument.</li>
<li>Map a ReportDocument to a MemoryStream of a pdf file.</li>
</ol>
<pre name="code" class="c-sharp">
IMapper&lt;int, DataSet&gt; _dataProvider;
IMapper&lt;DataSet, ReportDocument&gt; _reportGenerator;
IMapper&lt;ReportDocument, Stream&gt; _pdfReportExporter;

public Stream GetCustomerReport(int customerId) {
  return _pdfReportExporter.Map(
           _reportGenerator.Map(
             _dataProvider.Map(customerId)));
}
</pre>
<p>Pretty nice huh?   Well not that nice.  If you&#8217;re a naming perfectionist like I this should make you shiver.  When it comes to maintainability, good intention-revealing namespace, class, and method names are worth a million unit tests and n-tier architectures.  Forget requirements docs and self-documenting code, proper naming is the number one tool for communicating our intent.</p>
<p>I lecture my team on this constantly and yet I allow myself the use of the the term &#8220;Map&#8221;?!  A generic term that could indicate anything except (unless you&#8217;re a cartographer) a concept from your ubiquitous langauge.  I should be ashamed.</p>
<p>We want to keep our generic IMapper interface though, it&#8217;s so slick, allows us to write minimal code and you you could easily imagine it coming in handy.  For example, perhaps as the domain itself becomes more complicated, it becomes useful to break our IMapper&lt;int, DataSet&gt; down further.<br />
 1. The integer is get mapped to a Customer entity.<br />
 2. This gets mapped to a ReportSpecification.<br />
 3. The ReportSpecification is evaluated and mapped to a StoredProcedureInvocation<br />
 4. The procedure is executed and finally returns our DataSet. </p>
<p>You could imagine all sorts of neat little tricks you could play with our IoC container &#8211; we could have it automatically link transforms together or subsitute out implemenations.  Simply by knowing that all these components transform one object to another we could configure automatic caching, deferred execution proxies, and so on.  All things that are made far easier because all transformations are achieved via IMapper.Map.</p>
<p>What we really need is a way to introduce aliases for the Map() method.  Preferably ones that depend on the input and output type.  So why sit there scratching our heads?  C# is a flexible enough language, let&#8217;s just let&#8217;s do that thing that I just said.</p>
<pre name="code" class="c-sharp">
public CustomerOrderReportGenerator : IMapper&lt;DataSet, ReportDocument&gt; {
  public ReportDocument Map(DataSet data) {
    // implementation
  }
}
public partial static class AliasExtensions {
  public static ReportDocument GenerateReportFrom(this IMapper&lt;ReportDocument, DataSet&gt; mapper, DataSet ds) {
    return mapper.Map(ds); }
}
</pre>
<p>And now we have aliases:</p>
<pre name="code" class="c-sharp">
  _pdfReportExporter.Export(
    _reportGenerator.GenerateReportFrom(
      _dataProvider.GetOrderDataFor(customerId)));
</pre>
<p>The poor readability of this bothers me.  The LISPers among us might not mind reading backwards through a stack of nested parentheses but as a fan of fluent interfaces I&#8217;d like to see my code read as close to natural english as possible.  </p>
<p>Same trick, now featuring double dispatch!</p>
<pre name="code" class="c-sharp">
public partial static class AliasExtensions {
  public static ReportDocument ComposeIntoReportUsing(this DataSet ds, IMapper&lt;ReportDocument, DataSet&gt; mapper) {
    return mapper.Map(ds); }
}
</pre>
<p>Allows us to do:</p>
<pre name="code" class="c-sharp">
  return _dataProvider
    .GetOrderDataFor(customerId)
    .ComposeIntoReportUsing(_reportGenerator)
    .ToStreamUsing(_pdfReportExporter);
</pre>
<p>And there you have it.  Nice, fluent, and composable. </p>
<p>What do you guys think?  <b>Aliased Maps</b> a good name?</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fgeorgemauer.net%2fblog%2fhey-i-think-ive-invented-a-new-pattern%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fgeorgemauer.net%2fblog%2fhey-i-think-ive-invented-a-new-pattern%2f" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://georgemauer.net/blog/hey-i-think-ive-invented-a-new-pattern/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Enable/Disable FusionLog Powershell script</title>
		<link>http://georgemauer.net/blog/enabledisable-fusionlog-powershell-script/</link>
		<comments>http://georgemauer.net/blog/enabledisable-fusionlog-powershell-script/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 17:01:21 +0000</pubDate>
		<dc:creator>togakangaroo</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://georgemauer.net/blog/?p=116</guid>
		<description><![CDATA[If you use Windows and don&#8217;t use Powershell you should.  Really you should.  It&#8217;s great for getting all the little repetitive things out of the way.
Like for example enabling/disabling your Fusion Log every time you need to figure out why assembly binding has gone wrong.  So here you go.  Just put [...]]]></description>
			<content:encoded><![CDATA[<p>If you use Windows and don&#8217;t use <a href="http://technet.microsoft.com/en-us/scriptcenter/dd742419.aspx">Powershell</a> you should.  Really you should.  It&#8217;s great for getting all the little repetitive things out of the way.</p>
<p>Like for example enabling/disabling your Fusion Log every time you need to figure out why assembly binding has gone wrong.  So here you go.  Just put these in your profile:</p>
<pre name="code" class="py">
function global:Enable-FusionLog {
	Remove-ItemProperty HKLM:Software\Microsoft\Fusion -name EnableLog -ErrorAction SilentlyContinue
	[void](New-ItemProperty  HKLM:Software\Microsoft\Fusion -name EnableLog -propertyType dword -ErrorAction Stop)
	Set-ItemProperty  HKLM:Software\Microsoft\Fusion -name EnableLog -value 1 -ErrorAction Stop
	Write-Host "Fusion log enabled.  Do not forget to disable it when you are done"
}
function global:Disable-FusionLog {
	Remove-ItemProperty HKLM:Software\Microsoft\Fusion -name EnableLog -ErrorAction SilentlyContinue
	Write-Host "Fusion log disabled"
}
</pre>
<p>Awesome.</p>
<p>Also we talked Powershell at yesterday&#8217;s GNO.NET and Cody Gros showed <a href="http://www.powergui.org/index.jspa">PowerGUI </a>- which a totally free and seemingly awesome powershell editor.  Woo!</p>
]]></content:encoded>
			<wfw:commentRss>http://georgemauer.net/blog/enabledisable-fusionlog-powershell-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rhino.Mocks 3.6 Intro &#8211; What You Actually Need To Know</title>
		<link>http://georgemauer.net/blog/rhino-mocks-intro/</link>
		<comments>http://georgemauer.net/blog/rhino-mocks-intro/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 14:28:06 +0000</pubDate>
		<dc:creator>togakangaroo</dc:creator>
				<category><![CDATA[ALT.Net]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[intro]]></category>
		<category><![CDATA[mocking]]></category>
		<category><![CDATA[rhino.mocks]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://georgemauer.net/blog/98/</guid>
		<description><![CDATA[What&#8217;s a Mock?
For the purpose of this essay a mock is an object that uses the object oriented concept of polymorphism to create an alternate implementation of a class or interface.  Essentially, a mock is just a fake version of an object.
A mock is used for two things

Stub: Stand in for a service and [...]]]></description>
			<content:encoded><![CDATA[<h2>What&#8217;s a Mock?</h2>
<p>For the purpose of this essay a mock is an object that uses the object oriented concept of polymorphism to create an alternate implementation of a class or interface.  Essentially, a mock is just a fake version of an object.</p>
<p>A mock is used for two things</p>
<ol>
<li><strong>Stub:</strong> Stand in for a service and provide alternate, simpler method implementations.  An example would be to substitute for an object that would normally query the database – instead of querying the database the stub object will simply return a canned response.</li>
<li><strong>Spy:</strong> Detect whether an object was used in a certain way.  An example would be when testing an object that decides whether to call ui.NotifyUser() depending on some criteria.  A spy can stand in for the ui object and call tell you if the NotifyUser() method was called.</li>
<p>Don&#8217;t worry if that is a bit obtuse, it should become clear soon
</ol>
<p><span id="more-98"></span></p>
<h2>Why Would You Need A Mock?</h2>
<p>Consider the domain of liquid storage.  </p>
<ul>
<li>We have a Container which has Contents.</li>
<li>By totalling all the transfers into and out of the container we can calculate the expected Quantity of the Contents &#8211; this is called the Book Value.</li>
<li>We can also physically measure the Quantity &#8211; whenever we do, we add the measured Quantity, along with it&#8217;s type (whether it was taken Automatically or Manually) to the store of Physicals.</li>
<li>We can at any time request a measurement of the Variance of the Contents.  This Quantity is defined as the last manual Physical minus the Book Value.</li>
<li>Of course when a Varaiance is calculated, it needs to get Logged.</li>
</ul>
<pre name="code" class="c-sharp">
  public class Contents {
          public Quantity Book { get; set; }
  }
  public interface IPhysicals {
    Quantity GetLastFor(Contents contents, PhysicalType physicalType);
  }
  public enum PhysicalType { Manual, Automatic }
  public class Quantity {
     public double Amount { get; set; }
    public string UnitOfMeasure { get; set; }
  }
  public interface IEventLogger {
    void Log(string message);
  }
  public class VarianceCalculator {
    IPhysicals _physicals;
    IEventLogger _log;
    public VarianceCalculator(IPhysicals physicals, IEventLogger events) {
      _physicals = physicals;
      _log = events;
    }

    public Quantity GetVariance(Contents contents) {
      Quantity p = _physicals.GetLastFor(contents, PhysicalType.Manual);
      if (p == null)
        return null;
      var variance = new Quantity() { Amount = p.Amount - contents.Book.Amount };
      _log.Log(String.Format("New variance calculated: {0} - {1} = {2}",
               p.Amount, contents.Book.Amount, variance.Amount));
      return variance;
    }
  }
</pre>
<p><a href="http://code.google.com/p/gim-projects/source/browse/Tutorial.RhinoMocks/app/Tutorial.RhinoMocks.Tests/Domain.cs">[Code Link]</a></p>
<p>The only logic here is in the VarianceCalculator.GetVariance method so let&#8217;s test that.</p>
<p>For any action there are two things that can be checked: the output, and any side-effects.  So let&#8217;s write down all the conditions and side-effects that we expect.</p>
<ol>
<li>If the contents object <span style="background-color:yellow">does have a manual physical</span> then the method should return the correctly calculated quantity</li>
<li>If the contents object <span style="background-color:yellow">does have a manual physical</span> then the method <span style="background-color:lime">should log the calculation</span>.</li>
<li>If the contents object <span style="background-color:yellow">does not have a manual physical</span> then the method should return null</li>
<li>If the contents object <span style="background-color:yellow">does not have a manual physical</span> then the method <span style="background-color:lime">should not log anything</span>.</li>
</ol>
<p><img src="http://georgemauer.net/blog/wp-content/uploads/2009/10/102109_1429_1.png" alt="" /></p>
<p>Notice that an external service (IPhysicals) is used to retrieve the physical that will be used.  We do not want to actually have to set up and query the database so we need something that performs the duties of a <strong>stub</strong>.  Also notice that we need to check whether the calculation results were passed off to a logger object.  Going on our definitions from above, this requires a <strong>spy</strong>.</p>
<h2>Our Tests</h2>
<p>Given that we have four points above we should write four tests.  Here they are written in an abstract class that leaves gaps for how to to actually set-up the mocks.  We will create implement this abstraction in the next two sections.</p>
<pre name="code" class="c-sharp">
  [TestFixture]
  public abstract class VarianceCalculatorTests {
    protected abstract void BuildMocks(Quantity lastManualPhysical);
    protected abstract VarianceCalculator GetCalculator();
    protected abstract void AssertLoggerWasCalled(bool expectLoggerCalled);

    readonly Contents _contents = new Contents() {
      Book = new Quantity() { Amount = 700 }
    };

    [Test]
    public void Has_physical__Variance_is_physical_minus_book() {
      BuildMocks(new Quantity() { Amount = 1000 });
      var variance = GetCalculator().GetVariance(_contents);
      Assert.That(variance.Amount, Is.EqualTo(300));
    }
    [Test]
    public void Has_physical__Calculation_is_logged() {
      BuildMocks(new Quantity());
      GetCalculator().GetVariance(_contents);
      AssertLoggerWasCalled(true);
    }
    [Test]
    public void Has_no_physical__Variance_is_null() {
      BuildMocks(null);
      var variance = GetCalculator().GetVariance(_contents);
      Assert.IsNull(variance);
    }
    [Test]
    public void Has_no_physical__Calculation_is_not_logged() {
      BuildMocks(null);
      GetCalculator().GetVariance(_contents);
      AssertLoggerWasCalled(false);
    }
  }
</pre>
<p><a href="http://code.google.com/p/gim-projects/source/browse/Tutorial.RhinoMocks/app/Tutorial.RhinoMocks.Tests/VarianceCalculatorTests.cs">[Code Link]</a></p>
<h2>Doing It Manually</h2>
<p>In the interest of going slow, let&#8217;s first implement the above test fixture manually.</p>
<p style="text-align: center"><strong>MOCKS CANNOT DO ANYTHING THAT YOU CANNOT DO YOURSELF MANUALLY!</strong></p>
<p>If you do not need any further convincing then you can skip to the next section.</p>
<p>When you manually create an alternate implementation the resulting objects are traditionally called &#8220;Fakes&#8221;.  Here is a fake implementation of IPhysicals that can stub out calls to physicals.GetLastFor()</p>
<pre name="code" class="c-sharp">
  public class FakePhysicalsStub : IPhysicals {
    private Quantity _lastPhysical;
    public FakePhysicalsStub(Quantity lastPhysical) {
      _lastPhysical = lastPhysical;
    }
    public Quantity GetLastFor(Contents contents, PhysicalType physicalType) {
      return _lastPhysical;
    }
  }
</pre>
<p>And here is a fake implementation of an IEventLogger spy:</p>
<pre name="code" class="c-sharp">
  public class FakeEventLoggerSpy : IEventLogger {
    private IList&lt;string&gt; _messagesLogged = new List&lt;string&gt;();
    public void Log(string message) {
      _messagesLogged.Add(message);
    }
    public bool WasLogged(Regex expectedMessageMatcher) {
      return _messagesLogged.Any(m =&gt; expectedMessageMatcher.IsMatch(m));
    }
  }
</pre>
<p>And here is how you would use these:</p>
<pre name="code" class="c-sharp">
  public class ManualFakes_VarianceCalculatorTests : VarianceCalculatorTests {
    private FakeEventLoggerSpy _logger;
    private FakePhysicalsStub _physicals;
    protected override void BuildMocks(Quantity lastManualPhysical) {
      _physicals = new FakePhysicalsStub(lastManualPhysical);
      _logger = new FakeEventLoggerSpy();
    }

    protected override VarianceCalculator GetCalculator() {
      return new VarianceCalculator(_physicals, _logger);
    }

    protected override void AssertLoggerWasCalled(bool expectLoggerCalled) {
      Assert.That(_logger.WasLogged(new Regex(".+")), Is.EqualTo(expectLoggerCalled));
    }
  }
</pre>
<p><a href="http://code.google.com/p/gim-projects/source/browse/Tutorial.RhinoMocks/app/Tutorial.RhinoMocks.Tests/ManualFakes_VarianceCalculatorTests.cs">[Code Link]</a></p>
<h2>Getting Rhino.Mocks to Do It for You</h2>
<p>Creating fakes manually is not very difficult but it does require some thought.  In addition you end up having to maintain the fakes as well as your actual implementations when making any changes to the underlying types.  On the other hand, creating manual fakes will always be more powerful and flexible than an automatic alternative so do not be afraid to use them when needed.  That being said, <a href="http://www.ayende.com/projects/rhino-mocks.aspx">Rhino Mocks</a> is a library thatwhen properly used should be able to cover 99% of your automatic mock creation needs.  In fact, I have never really encountered a situation where its abilities proved inadequate.  </p>
<p>It is important to remember that Rhino.Mocks has been around for some time and offers several different APIs.  This tutorial targets the version of the API as of Rhino.Mocks 3.6 – while improvements are possible, there have not been any truly major changes in the last few versions and this API style can probably be considered final.</p>
<h3>Mock Creation</h3>
<p>First things first; how do you use Rhino.Mocks to create our stub and spy instances?  Rhino.Mocks does not distinguish between the two when creating objects &#8211; all classes created by Rhino.Mocks can be used as both stubs and spys.  The easiest way to create them is to use the MockRepository static class:</p>
<p><img src="http://georgemauer.net/blog/wp-content/uploads/2009/10/102109_1429_2.png" alt="" /></p>
<p>This class has two methods of consequence, <em>GenerateMock&lt;T&gt;()</em> and <em>GenerateStub&lt;T&gt;()</em>.  There is very little <a href="http://ayende.com/Wiki/Rhino+Mocks+3.5.ashx">difference between these two</a> and you can feel perfectly safe using only <em>GenerateStub&lt;T&gt;().</em> Calling </p>
<pre name="code" class="c-sharp">IEventsLogger mock = MockRepository.GenerateStub&lt;IEventsLogger&gt;()</pre>
<p>Will return an that implements <em>IEventsLogger</em> and can stand in for all its instances.</p>
<h3>Stubbing</h3>
<p>By default, any calls to <em>_physicals.GetLastFor()</em> will return null but we can set up this mock object to act as a stub:</p>
<pre name="code" class="c-sharp">
  _physicals = MockRepository.GenerateStub&lt;IPhysicals&gt;();
  _physicals.Stub(x =&gt; x.GetLastFor(
      Arg&lt;Contents&gt;.Is.Anything, Arg&lt;PhysicalType&gt;.Is.Anything) ).Return(lastManualPhysical);
</pre>
<p>This API uses extension methods and LINQ Expressions to allow you to specify which method you want to stub and what to return.  When <em>_physicals.GetLastFor()</em> is called after this code executes, the object lastManualPhysical will be returned.  </p>
<p>Also, as the above code implies, you can constrain the stub based on certain types of inputs.</p>
<pre name="code" class="c-sharp">
  _physicals.Stub(x =&gt; x.GetLastFor(
      Arg&lt;Contents&gt;.Is.Null, Arg&lt;PhysicalType&gt;.Is.Equal(PhysicalType.Automatic))).Return(someOtherPhysical);
</pre>
<p>Is legal and works pretty much like you would expect.  Many constraint types are available. There are also several shortcuts.  For example the above can be expressed as</p>
<pre name="code" class="c-sharp">_physicals.Stub(x =&gt; x.GetLastFor(null, PhysicalType.Automatic).Return(someOtherPhysical);</pre>
<p>Since all arguments have to be matched exactly. Also the first stub (where any arguments are acceptable) can be more quickly expressed as:</p>
<pre name="code" class="c-sharp">_physicals.Stub(x =&gt; x.GetLastFor(null, null)).IgnoreArguments().Return(lastManualPhysical);</pre>
<p>Several other syntaxes are also available, but as of Rhino.Mocks 3.6 these are the only ones that are preferred.</p>
<h3>Spying</h3>
<p>Now that we have discussed stubbing, let&#8217;s discuss the syntax for creating spy objects.  As stated before, all objects created with Rhino.Mocks can be both stubs and spys so their creation is exactly the same.  We only need to learn the syntax for how to verify whether a method was called or not.  This is achieved with the AssertWasCalled() and AssertWasNotCalled() extension methods.</p>
<p>These methods have very similar syntax to Stub() with the exception that IgnoreArguments(), and other constraints shortcuts are provided in a constraints parameter, rather than as extension methods of their own.  So, to specify that our IEventsLogger.Log() method was called we need to do this:</p>
<pre name="code" class="c-sharp">_logger.AssertWasCalled(x =&gt; x.Log(null), c =&gt; c.IgnoreArguments());</pre>
<p>Or to specify that it was not called:</p>
<pre name="code" class="c-sharp">_logger.AssertWasNotCalled(x =&gt; x.Log(null), c =&gt; c.IgnoreArguments());</pre>
<p>If you want a little more finely grained control over the argument constraints you can do that too.  For example the following asserts that Log() was called and that the input was not null or empty:</p>
<pre name="code" class="c-sharp">
  _logger.AssertWasCalled(x =&gt; x.Log(
    Arg&lt;string&gt;.IsMatches(Is.Matching&lt;string&gt;(m =&gt; !String.IsNullOrEmpty(m)))));</pre>
<p>Of course, as before, if you know the exact argument that you want to check for you can do it more easily:</p>
<pre name="code" class="c-sharp">_logger.AssertWasCalled(x =&gt; x.Log("this exact message was called"));</pre>
<p>Here is the full implementation for the base VarianceCalculatorTests:</p>
<pre name="code" class="c-sharp">
  public class RhinoMocks_VarianceCalculatorTests : VarianceCalculatorTests {
    private IEventLogger _logger;
    private IPhysicals _physicals;
    protected override void BuildMocks(Quantity lastManualPhysical) {
      _physicals = MockRepository.GenerateStub<IPhysicals>();
      _physicals.Stub(x => x.GetLastFor(Arg<Contents>.Is.Anything, Arg<PhysicalType>.Is.Anything)).Return(lastManualPhysical);
      _logger = MockRepository.GenerateStub<IEventLogger>();
    }

    protected override VarianceCalculator GetCalculator() {
      return new VarianceCalculator(_physicals, _logger);
    }

    protected override void AssertLoggerWasCalled(bool expectLoggerCalled) {
      if (expectLoggerCalled)
        _logger.AssertWasCalled(x => x.Log(null),
            c => c.Constraints(Is.Matching<string>(m => !String.IsNullOrEmpty(m))));
      else
        _logger.AssertWasNotCalled(x => x.Log(null), c => c.IgnoreArguments());
    }
  }
</pre>
<p><a href="http://code.google.com/p/gim-projects/source/browse/Tutorial.RhinoMocks/app/Tutorial.RhinoMocks.Tests/RhinoMocks_VarianceCalculatorTests.cs">[Code Link]</a></p>
<h3>Other Stuff</h3>
<p>You have now learned virtually everything you need to know to effectively use Rhino.Mocks.  A couple other occasionally used syntaxes are:</p>
<pre name="code" class="c-sharp">
  _physicals.Stub(x =&gt; x.GetLastFor(null,
    Arg&lt;PhysicalType&gt;.Is.Anything)).Throw(new ArgumentNullException ());
</pre>
<p>Which causes (you guessed it) an ArgumentNullException to be thrown when GetLastFor() is passed a null contents object.</p>
<p>If you have played around with the stubbing code above, you might have noticed that the stub will work only once.  That is, you will get the desired result the first time you call <em>_physicals. GetLastFor()</em> but will go back to returning null for subsequent calls.  To get the desired result you can set the stub up multiple times, or use the <em>Repeat</em> syntax.</p>
<pre name="code" class="c-sharp">
  _physicals.Stub(x =&gt; x.GetLastFor(null,
    Arg&lt;PhysicalType&gt;.Is.Anything)).Return(null).Repeat.Any();
</pre>
<p>Also, you can pass in a delegate to be executed when a stubbed method is called.  This is primarily useful when doing integration and benchmark tests or when working with a timer.</p>
<pre name="code" class="c-sharp">
  _physicals.Stub(x =&gt; x.GetLastFor(null, PhysicalType.Automatic)).IgnoreArguments().Do(
    new Func&lt;Contents, PhysicalType, Quantity&gt;((c, t) =&gt; {
      Console.WriteLine("Method Called With {0}, {1}", c, t);
      return null;
    })
  );
</pre>
<p>A situation where you are finding yourself having to do something like this might be an indicator that you should just create a fake manually.</p>
<p>It is also possible to create mocks of concrete classes rather than just interfaces.  However, this can be a little tricky since there is no way for Rhino.Mocks to stop the constructor from executing.  You must therefore either provide a parameter-less protected constructor or pass in objects to be used.</p>
<pre name="code" class="c-sharp">
  public class MyClass {
    string _dependency;
    public MyClass(string dependency) {
      _dependency = dependency;
    }
  }
  //
  MyClass x = MockRepository.GenerateStub&lt;MyClass&gt;("");
</pre>
<p>A word of caution however, if you find yourself really needing to mock a concrete object perhaps you might want to consider extracting an interface, or including the object in your test.</p>
<p>And that&#8217;s it.  There is a lot of other stuff in Rhino.Mocks but it is almost guaranteed that you don&#8217;t need to know it as the above will cover nearly every single testing scenario.</p>
<h2>Sample Code and on Testing Style</h2>
<p>The sample code from this tutorial is provided <a href="http://code.google.com/p/gim-projects/source/browse/">here</a>.  Please note that there are three sets of tests.  <a href="http://code.google.com/p/gim-projects/source/browse/Tutorial.RhinoMocks/app/Tutorial.RhinoMocks.Tests/ManualFakes_VarianceCalculatorTests.cs">VarianceCalculatorTests.cs contains the base class</a> which defines the tests used above. <a href="http://code.google.com/p/gim-projects/source/browse/Tutorial.RhinoMocks/app/Tutorial.RhinoMocks.Tests/ManualFakes_VarianceCalculatorTests.cs">ManualFakes_VarianceCalculatorTests implement the tests using manually built fakes</a> and <a href="http://code.google.com/p/gim-projects/source/browse/Tutorial.RhinoMocks/app/Tutorial.RhinoMocks.Tests/RhinoMocks_VarianceCalculatorTests.cs">RhinoMocks_VarianceCalculatorTests implements them using Rhino.Mocks</a>.</p>
<p>Although it is ultimately a matter of preference, it should be noted that the tests written so far are not done in what in what is a somewhat dated style.  The currently predominant testing technique of <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">Behavior Driven Development (BDD)</a> is usually preformed and recommended.  To that end, another series of tests is provided inside the BDD directory to demonstrate how such tests might look.</p>
<p>So now you know how to use Rhino.Mocks.  I urge you to investigate its use further and learn as much as you can about Unit Testing, Test Driven Development, and Behavior Driven Development.  </p>
<p>Please feel free to leave any further questions in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://georgemauer.net/blog/rhino-mocks-intro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Like 300 only geekier</title>
		<link>http://georgemauer.net/blog/like-300-only-geekier/</link>
		<comments>http://georgemauer.net/blog/like-300-only-geekier/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 04:15:55 +0000</pubDate>
		<dc:creator>togakangaroo</dc:creator>
				<category><![CDATA[NOLA]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://georgemauer.net/blog/?p=83</guid>
		<description><![CDATA[I just got back from the New Orleans Barcamp and I&#8217;m going to go ahead and join everyone in singing its praises.  Day 1 was great &#8211; full of interesting presentations, introductions and exchanging of ideas.  I even got to present twice, once on Test Driven Development and again later in the evening with Stephen [...]]]></description>
			<content:encoded><![CDATA[<p>I just got back from the <a href="http://barcamp.org/BarCampNOLA">New Orleans Barcamp</a> and I&#8217;m going to go ahead and <a href="http://twitter.com/#search?q=barcampnola">join everyone</a> in singing its praises.  Day 1 was great &#8211; full of interesting presentations, introductions and exchanging of ideas.  I even got to present twice, once on Test Driven Development and again later in the evening with <a href="http://blog.unhandled-exceptions.com/">Stephen Bohlen&#8217;s</a> <a href="http://virtualaltnet.com/Recordings/Show/41">slide-deck on Domain Driven Design</a>. However, fun as it was, it went roughly how I expected, so I probably would not be blogging about its success alone.</p>
<p>It is the second day that was destined for real magic.  The challenge was simple: <em>&#8220;Do something to help with the organization of the leagues of people who donate their time to volunteer for the New Orleans public school district&#8221;</em>.  Those familiar with software development in general &#8211; and the challenge of herding hungover techies who get in at 10am to start and complete a project by 4pm in particular &#8211; will recognize it as simply jaw-dropping.  Especially when &#8220;something&#8221; is expanded to mean &#8220;create a full blown, maintainable, multi-media website to bring together and thank volunteers&#8221; &#8211; wowee.  And yet I&#8217;m proud to announce <a href="http://www.nolaschoolvolunteers.org/">http://www.nolaschoolvolunteers.org/</a> which as of this morning did not exist and now does all those things and more.  Everything you see, including domain name, CMS installation, layout, and much of the content was created in one afternoon by a group of dedicated barcamp attendees.</p>
<p>In a word, everyone there was just astoundingly professional.  How professional?  Well a room full of 15 geeks from different backgrounds and diciplenes spent all of 10 minutes debating language choice and platform.  The conversation was literally:</p>
<blockquote><p>- So it sounds like  PHP is our lowest common denominator and we&#8217;ve got a PHP guru?</p>
<p>- Yup.  So let&#8217;s do PHP.</p>
<p>- Ok.  Can we do this in wordpress?</p>
<p>- I think so.  We&#8217;ve got a couple guys that are good at wordpress and some more that are familar with it.</p>
<p>- Wordpress it is.</p></blockquote>
<p>And if that isn&#8217;t shocking enough then we did it!  In one fell swoop and in no small part through the leadership of <a href="http://twitter.com/Tritico">Matthew Tritico</a> and others; requirements were defined, refined, scoped back, matched up with a technology, assigned,  implemented, and integrated in a whirlwind six hour session that I consider among the most productive hours of my life.</p>
<p>Oh and luck.  I&#8217;m going to go ahead and say that a lot of luck was also involved.</p>
<p>So take aways:</p>
<ol>
<li>Never underestimate the collective power of an enthusiastic, experienced, and focused group.  The trick is getting all three.</li>
<li>Value of someone who&#8217;s done it once before is that of ten bright people. Value of someone whose done it twice is that of twenty.</li>
<li>Take the time and pick the right tool for the job.  The site was created in wordpress with a variety of plugins, and a healthy dose of google products.  A huge amount of functionality with hardly any code at all!  Microsoft take note &#8211; this is RAD developoment done right.  It is possible, but drag-drop and a fancy IDE is no replacement for true knowledge.</li>
<li>Finally, equally as important as the availability of the right component is the ability to integrate with the rest of the application.  Do not take this for granted &#8211; the excellent ecosystem of wordpress plugins was a major deciding factor for us and cut down considerably on integration time that we did not have.</li>
</ol>
<p>So again, a spectacular job by all.  A lot of great relationships fostered, a lot of tech talk, and one kick-ass site banged out in an afternoon.  Frankly, given the glacial pace at which I see projects progressing in the enterprise space, I really needed to see this.  I&#8217;m not even sure what I think about this yet &#8211; was it all luck or did I really learn something interesting?</p>
<p>I think likely the latter.</p>
]]></content:encoded>
			<wfw:commentRss>http://georgemauer.net/blog/like-300-only-geekier/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Screencast: Keeping Features Out Your Way With Branching</title>
		<link>http://georgemauer.net/blog/screencast-keeping-features-out-your-way-with-branching/</link>
		<comments>http://georgemauer.net/blog/screencast-keeping-features-out-your-way-with-branching/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 19:12:23 +0000</pubDate>
		<dc:creator>togakangaroo</dc:creator>
				<category><![CDATA[ALT.Net]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://nothingyoumissed.wordpress.com/?p=62</guid>
		<description><![CDATA[Pop quiz:  What&#8217;s the software developer&#8217;s biggest enemy?  It&#8217;s not marketing.  It&#8217;s not those snot-nosed DBAs.  The rigid chair that will invariably give you arthritis?  Nah.  Your know-nothing boss?  Not even close.  No, the developer&#8217;s biggest enemy is the customer.
That&#8217;s right customers and their god d*mn feature requests and bug reports!  Life would be so [...]]]></description>
			<content:encoded><![CDATA[<p>Pop quiz:  What&#8217;s the software developer&#8217;s biggest enemy?  It&#8217;s not marketing.  It&#8217;s not those snot-nosed DBAs.  The rigid chair that will invariably give you arthritis?  Nah.  Your know-nothing boss?  Not even close.  No, the developer&#8217;s biggest enemy is the customer.</p>
<p>That&#8217;s right customers and their god d*mn feature requests and bug reports!  Life would be so much easier without them.  And acknowledging the absurdity of that statement, unless you are some kind of programmer <a href="http://en.wikipedia.org/wiki/Adonis">Adonis</a> (which unlike a regular Adonis physically implies only that your esophagus is invulnerable to lesions caused by <a href="http://www.bawls.com/">Bawls</a>) and write flawless code you will have to deal with feature requests that can rapidly pile up and overwhelm your development process.</p>
<p>I had mentioned previously on this blog that I am working with a team of Indian contractors and this is exactly what they found happening with the latest <em>high stakes omg-fix-this-now-or-we-all-die </em>release.  The team was behind and the release went out mere minutes before users started working with it.  Of course in the rush to finish on time bugs cropped up and features were left out.  Lots of features.</p>
<p>So immediately the next morning, with tickets raining down and demands for new drops every day the team got to work.  And the daily releases never came.  On the 3rd day we finally dived into their process with them to identify the problem.  </p>
<p>Simply speaking, they couldn&#8217;t reach a stopping point.  By the time certain features were ready to go others were half-implemented and so no release could be scheduled.  It was like some sort of real life <a href="http://en.wikipedia.org/wiki/Zeno's_paradoxes">Zeno&#8217;s paradox</a>.  Fortunately this one has a solution.  Fully acknowledging that it is probably named differently in a dozen books and Agile pamphlets (just not any that I&#8217;ve seen), I call it branch-per-release or &#8220;how to use source control to get yourself out of a tight spot&#8221;. </p>
<p>The idea is blatantly simple:</p>
<ol>
<li>Chose a release date</li>
<li>Decide which features will fit in that release date</li>
<li>Use your source control chops to create a branch for that release</li>
<li>Decide what release each of the features on your plate goes in</li>
<li>Create a branch for each of those releases</li>
<li>Implement each feature set in the branch for its release</li>
<li>When development on a branch is completed and tested, reintegrate into trunk.</li>
<li>Rinse, repeate.</li>
</ol>
<p>I have created a presentation and a series of screencasts (3 x 5 minutes thank you <a href="http://www.jingproject.com/">Jing</a>) to demonstrate the process.  And here they all are:</p>
<ul>
<li><a href="http://docs.google.com/Presentation?id=dnmmm9d_105c5r2mwhr">Presentation</a> &#8211; 6 Slides, Google Docs format (so its viewable in-browser)</li>
<li><a href="http://content.screencast.com/users/togakangaroo/folders/BranchVersioningDemo/media/b38e3992-0a2e-4c3e-8084-4f5d0fb01887/p1.swf">Part 1</a>  </li>
<li><a href="http://content.screencast.com/users/togakangaroo/folders/BranchVersioningDemo/media/fbe88cba-31ff-4318-a002-fbaffed1656b/p2.swf">Part 2</a></li>
<li><a href="http://content.screencast.com/users/togakangaroo/folders/BranchVersioningDemo/media/fbd8e5e8-98a7-41e4-a523-2f8bd82f0879/p3.swf">Part 3</a></li>
</ul>
<p>Apparently embedding videos on wordpress.com is a pain in the *ss (as is code highlighting) so as mere links they must stay.</p>
<p><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0;" src="http://i.creativecommons.org/l/by-sa/3.0/us/88x31.png" /></a><br />This <span>work</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/us/">Creative Commons Attribution-Share Alike 3.0 United States License</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://georgemauer.net/blog/screencast-keeping-features-out-your-way-with-branching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The GoGaRuConf Pr0n Affair Rhinos vs Rabbits and A Challenge</title>
		<link>http://georgemauer.net/blog/rhinos-vs-rabbits/</link>
		<comments>http://georgemauer.net/blog/rhinos-vs-rabbits/#comments</comments>
		<pubDate>Fri, 01 May 2009 23:11:57 +0000</pubDate>
		<dc:creator>togakangaroo</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://nothingyoumissed.wordpress.com/?p=57</guid>
		<description><![CDATA[Well I don&#8217;t have many (any?) readers so I&#8217;m not going to go into depth linking and summarizing something that is
 handled in a million different places probably best on Martin Fowler&#8217;s blog (is the terminology blog correct here? Bible? Holy Testament?).
 
Super short version: Ruby on Rails prides itself on being an edgy community; at a conference, a [...]]]></description>
			<content:encoded><![CDATA[<p>Well I don&#8217;t have many (any?) readers so I&#8217;m not going to go into depth linking and summarizing something that is</p>
<div class="wp-caption alignright" style="width: 290px"><img src="http://www.lewa.org/lewa-wildlife-conservancy-pics/white_rhinocerous_portrait.jpg" alt="Gotta have at least one picture of a Rhino" width="280" height="358" /><p class="wp-caption-text">Gotta have at least one picture of a Rhino</p></div>
<p> handled in a million different places probably best on <a href="http://martinfowler.com/bliki/SmutOnRails.html">Martin Fowler&#8217;s blog</a> (is the terminology blog correct here? Bible? Holy Testament?).</p>
<p> </p>
<p>Super short version: Ruby on Rails prides itself on being an edgy community; at a conference, a slide deck contained a prolonged analogy between a technology and porn; people got offended.  There, that hits all the high notes.  I posted my thoughts as a comment on the <a href="http://www.hanselman.com/blog/DontGiveBileAPermalinkFindingBalanceWithinTheNoAssholeRule.aspx">hanselblog</a> but then thought hey, I really haven&#8217;t updated my own blog in a while and I actually have (what I think is) an original insight on this so here we go.</p>
<p>For the record, I am mostly with Martin Fowler and others who urge professionalism and think the presntation was in poor taste to begin with (as in a cheap use of a lame analogy) but I think that I have something else to add to the discussion.</p>
<p>Let me start with this, I am notoriously thick skinned.  Really.  Like a Rhino (see sidebar for gratuitous picture of a Rhino).  You would have to know me quite well to understand how deep it goes but suffice to say that it is a product of my life philosophy and I do not remember the last time I was truly offended.  That being said, I am hopefully not a jerk and do not expect others to hold to the same standard.  However, because I cannot use myself as a guage I have had immense difficulty walking the line between offensiveness and expressiveness.  This is something that I have been actively working on for years, and I would like to think with results (I somehow swindled a lovely girl into an engagement even).  Hence my keen interest in this current discussion of appropriateness.</p>
<p>All conversation of gender roles, stereotypes, and feelings aside I think the argument of really boils down to this:  </p>
<ol>
<li> The more edgy/expressive/offensive you get the more thin-skinned people you will exclude.  </li>
<li>If a community allows offensive behavior repeatedly then the offended parties will be excluded from that community.  </li>
<li>Why in the world would a tech movement want to exclude people &#8211; many brilliant people even &#8211; solely on these grounds?</li>
</ol>
<p>Logically, this argument is a check-mate.  You want your ideas to be inclusive?  Then you must work to be inclusive as well.</p>
<p>But there is a caveat.  Many things are offensive; why would thin-skinned people want to spend their lives in an offended state?  Seriously, a lot of this stuff is actually pretty funny, we&#8217;d for love you to join in.   </p>
<p>So here&#8217;s the proposal, how about we BOTH work on this?  Yes that means you rabbits as well as us rhinos.  I will continue learning about sensitivity, about people&#8217;s feelings, about why I shouldn&#8217;t use the N-word even though I think its constant use would strip it of its power, and all the other social norms.  I won&#8217;t compromise my expressiveness, but I will try to consciously and responsibly make an decision of who I will offend.  You in the meantime should watch George Carlin and Bill Hicks, try to see what&#8217;s funny about Family Guy, and maybe even occasionally read <a href="http://www.somethingawful.com">SomethingAwful</a> all with an open mind.  You must try to see humor on its own terms and to distinguish an bad person from a crass one.  You should do this seriously and with commitment.</p>
<p>The thing is that many people will probably take even this suggestion as offensive in itself, that I am suggesting people with &#8220;refined social standards&#8221; need to change as well as us juvenile bozos.  Here your own argument for sensitivity stands against you.   You must realize that for many people being sensitive to your feelings is f*ing difficult.  Like really really really hard.  I know that checking my speech almost always leaves a bad taste in my mouth that I have to then obsess over for hours afterwards. And if you still don’t care then F you.</p>
<p>I don&#8217;t have a crescendo of an ending planned so let me just state that I did indeed learn some things from this whole affair and am quite happy at the ideas that it has brought to the forefront.  I doubt that someone will seriously take me up on my challenge and I will continue down my own path of social learning regardless but if you’re really going to be intellectually honest you can hopefully admit that I have a point.  And then tag, you’re it.</p>
]]></content:encoded>
			<wfw:commentRss>http://georgemauer.net/blog/rhinos-vs-rabbits/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Of Cavemen Jeff Atwood and SOLID</title>
		<link>http://georgemauer.net/blog/caveman-marketing-jeff-atwood-and-solid/</link>
		<comments>http://georgemauer.net/blog/caveman-marketing-jeff-atwood-and-solid/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 18:57:45 +0000</pubDate>
		<dc:creator>togakangaroo</dc:creator>
				<category><![CDATA[ALT.Net]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://nothingyoumissed.wordpress.com/?p=51</guid>
		<description><![CDATA[Jeff Jeff Jeff,
Reading your blog has always been a bit like programmer masturbation, it mostly serves to make the reader feel great about what an inquisitive and intellectual developer they are.  That&#8217;s ok though, it keeps people reading and just through the sheer volume and accessibility of your writing you&#8217;ve pounded into people&#8217;s skulls some [...]]]></description>
			<content:encoded><![CDATA[<p>Jeff Jeff Jeff,</p>
<p>Reading <a href="http://www.codinghorror.com/blog/">your blog</a> has always been a bit like programmer masturbation, it mostly serves to make the reader feel great about what an inquisitive and intellectual developer they are.  That&#8217;s ok though, it keeps people reading and just through the sheer volume and accessibility of your writing you&#8217;ve pounded into people&#8217;s skulls some extremely useful ideas, frequently without them even realizing it.</p>
<p>Heck, it was you that got me into reading programming blogs (tip of the hat to<a href="http://steve-yegge.blogspot.com/"> Steve Yegge</a> as well) and that is precisely why this <a href="http://www.codinghorror.com/blog/archives/001225.html">whole tiff</a> <a href="http://blog.objectmentor.com/articles/2009/02/06/on-open-letter-to-joel-spolsky-and-jeff-atwood">with Uncle Bob</a> is just silly and your <a href="http://www.codinghorror.com/blog/archives/000856.html">latest defense</a> the lamest of all.  You reach far more people than Uncle Bob does, you acknowledge that the SOLID principles are good ones, you say that the problem is with capturing the ear of the uninformed &#8211; and then you put them down?  Give me a break!</p>
<p>I don&#8217;t have time to rant at <a href="http://www.codethinked.com/post/2009/02/11/Today-Ive-Realized-How-Far-We-Have-To-Go.aspx">length like others</a> have but consider this:</p>
<dl class="wp-caption alignright">
<dt class="wp-caption-dt"><img class="alignright" title="Captain Caveman" src="http://se2.selektive-erinnerung.de/wp-content/uploads/2008/05/captain-caveman1.jpg" alt="Captain Caveman!" width="215" height="286" /></dt>
</dl>
<p>You know who were really the original unreachables?  Cavemen.  Completely in isolation from each other they decided it a hassle constantly having to seek out rock outcropping roofs and moss mattresses and all on their own they started piling rocks on each other to make houses.</p>
<p>Sure when the Assyrians invented the arch the Egyptian and Aztec builders didn&#8217;t hear about it, but eventually the Romans came along and in that very Roman way searched out the best ideas and decided to apply them to their own projects.  Good thing the Assyrians didn&#8217;t have bloggers.  They might have declared the arch unfit for popularization due to the infeasability of their marketing.</p>
<p>We&#8217;re at the very beginning of this stuff, lets encourage the good ideas, no matter who is listening.</p>
<p><strong>Update:</strong> InfoQ has a <a title="Atwood/Splonsky vs Uncle Bob on SOLID roundup" href="http://www.infoq.com/news/2009/02/spolsky-vs-uncle-bob">roundup of the whole debacle</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://georgemauer.net/blog/caveman-marketing-jeff-atwood-and-solid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Error Handling and the Message Repackaging Anti-Pattern</title>
		<link>http://georgemauer.net/blog/error-handling-and-the-message-repackaging-anti-pattern/</link>
		<comments>http://georgemauer.net/blog/error-handling-and-the-message-repackaging-anti-pattern/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 23:28:10 +0000</pubDate>
		<dc:creator>togakangaroo</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[exceptionhandling]]></category>
		<category><![CDATA[projectmanagement]]></category>

		<guid isPermaLink="false">http://nothingyoumissed.wordpress.com/?p=42</guid>
		<description><![CDATA[I currently have an interesting responsibility at work.  I am functioning as the manager and single-point-of-contact for a team in India working on imporving the codebase for one of our more important ASP.Net sites.  I know what you&#8217;re thinkin.  Did I say interesting?  I meant infuriating.  At the very least I should get a good [...]]]></description>
			<content:encoded><![CDATA[<p>I currently have an interesting responsibility at work.  I am functioning as the manager and single-point-of-contact for a team in India working on imporving the codebase for one of our more important ASP.Net sites.  I know what you&#8217;re thinkin.  Did I say interesting?  I meant infuriating.  At the very least I should get a good &#8220;Lessons Learned&#8221; post out of this.</p>
<p>Overall the experience hasn&#8217;t been too bad though.  I&#8217;ve been managing to maintain a decent rapport with their project manager and team lead, deadlines have been missed, but no more than I secretly expected, and overall they seem like fairly competent guys.  Their work isn&#8217;t innovative, Agile, testable, or well factored, but its decent enough.</p>
<p>Except for the exceptions.</p>
<p>Browsing one of their recent commits to our SVN lately (ok, so technically speaking they couldn&#8217;t figure out Subversion so they ftp-ed and <em>I</em> did the commit for them) I was shocked to discover the following <a href="http://en.wikipedia.org/wiki/Anti-pattern">error-handling anti-pattern</a> repeated <strong>41 </strong>times!</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode"><span class="kwrd">try</span> {
  <span class="rem">// Do Stuff</span>
}
<span class="kwrd">catch</span>(Exception ex) {
  <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(ex.Message);
}</pre>
<p>Do I get to name it?  Let&#8217;s call it the message repackaging anti-pattern.  And in case you&#8217;re not already reeling from this, the following is a mildly edited-down version of the letter I sent (Notice the eschewed profanity.  I believe a not insignificant achievement.)</p>
<hr />Dear Team,</p>
<div>
<div>While looking through some of your committed code I noticed quite a few (a quick search shows 41) places where you have code of the following form.</div>
<div>
<table border="0" cellspacing="0" cellpadding="3" width="100%">
<tbody>
<tr>
<td width="100%">
<pre><span>try</span><span style="font-size:x-small;"> {
 </span><span>// ...</span><span style="font-size:x-small;">
}
</span><span>catch</span><span style="font-size:x-small;">(Exception ex) {
 </span><span>throw</span><span style="font-size:x-small;"> </span><span>new</span><span style="font-size:x-small;"> Exception(ex.Message);
}</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
<div>Let me be absolutely clear: This is the worst possible way of handling exceptions!</div>
<div>Let&#8217;s go over why:</div>
<div>
<ol>
<li><em>Not doing anything inside the exception.</em> If nothing happens within the catch block then what purpose does it serve? I have seen people prepare their code like this in anticipation of going back and adding logging at some later date. Although this is not necessarily the best logging solution, it is acceptable when you actually implement the code! However, preparing your method like this in anticipation of some future date does nothing but make the code difficult to read. It&#8217;s not like it is that hard to go back later and add a try&#8230;catch block; if you&#8217;re using a refactoring tool like CodeRush it is literally four keystrokes. </li>
<li><em>Catching the base Exception.</em> Not every exception can have something be done about it. The canonical example is an OutOfMemoryException or one implying the database might be down. Is there anything to do in this case other than drop the user to an error page? I would even go so far as to say that most exceptions fall in this category &#8211; you just can&#8217;t do anything about them.  I strongly encourage you to read <a title="Stop Catching Exceptions" rel="nofollow" href="http://gen5.info/q/2008/07/31/stop-catching-exceptions/">Stop Catching Exceptions</a> for a more in depth discussion.</li>
<li><em>Treating the message as if it were the most important thing</em>. Exceptions usually carry a heck of a lot more information than just their message. They carry their type and a StackTrace and a list of any inner exceptions. Many specializations of the Exception base have even more information specific to that type of error. Out of all that information, the message is arguably the <em>least</em> important &#8211; for debugging I would take a StackTrace over a message any day. But by creating an exception off of the message you are effectively stripping out all this useful stuff! If for some reason, you must create a new exception, at least use the constructor overload that includes the original error as an InnerException: new Exception(&#8221;I don&#8217;t know why I&#8217;m creating this&#8221;, ex);</li>
<li><em>Why create a new Exception object at all?</em> You already have a perfectly valid exception object. It is a simple matter to do:
<div>
<table border="0" cellspacing="0" cellpadding="3" width="100%">
<tbody>
<tr>
<td width="100%">
<pre><span>try</span><span style="font-size:x-small;"> {
 </span><span>// ...</span><span style="font-size:x-small;">
}
</span><span>catch</span><span style="font-size:x-small;">(Exception ex) {
 </span><span>// Log or otherwise handle the exception</span><span style="font-size:x-small;">
 </span><span>throw</span><span style="font-size:x-small;">; </span><span><span style="font-size:x-small;">// Same as throw ex;</span></span><span style="font-size:x-small;">
}</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
</li>
</ol>
</div>
<div>So in conclusion</div>
<div>
<ul>
<li>Don&#8217;t catch an exception if you aren&#8217;t going to do anything with it.</li>
<li>Try to catch exceptions at the appropriate level and for the appropriate task. (logging inside private methods is probably unnecessary)</li>
<li>Do not create a new exception, throw the old one.</li>
</ul>
</div>
<div>Please take this as healthy constructive criticism. I hope that you agree with me on these points and that we can take care of this issue properly from now on.</div>
</div>
<p> </p>
<hr />A bit harsh perhaps, but I feel like for all the reasons above the immensity of this mistake cannot be overstated.  If you are doing this in your code STOP NOW and apologize to the maintenance gods!  You might even need to sacrifice a goat to appease them.  It&#8217;s that bad.</p>
<p>In any case, the recent commit has only 38 instances of this error.  So at least we&#8217;re getting better!</p>
]]></content:encoded>
			<wfw:commentRss>http://georgemauer.net/blog/error-handling-and-the-message-repackaging-anti-pattern/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
