<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.0.2" -->
<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/"
	>

<channel>
	<title>Chris Holmes Online</title>
	<link>http://www.chrisholmesonline.com</link>
	<description>Adventures in .NET, Agile Development, parenting, music, football, movies, and more...</description>
	<pubDate>Tue, 20 May 2008 05:22:49 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.2</generator>
	<language>en</language>
			<item>
		<title>Backlog-In Development-Done</title>
		<link>http://www.chrisholmesonline.com/2008/05/19/backlog-in-development-done/</link>
		<comments>http://www.chrisholmesonline.com/2008/05/19/backlog-in-development-done/#comments</comments>
		<pubDate>Tue, 20 May 2008 05:22:49 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
	<category>.NET</category>
	<category>Agile Development</category>
	<category>Software Development</category>
		<guid isPermaLink="false">http://www.chrisholmesonline.com/2008/05/19/backlog-in-development-done/</guid>
		<description><![CDATA[Simon has a new post describing how they&#8217;ve revamped their planning board. I found it to be an interesting read because for once someone else&#8217;s board looks similar to ours. 
Our board has undergone a few makeovers as well over the past couple of years. In the beginning we tried to do what everyone else [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.agileinaction.com/">Simon</a> has a new post describing how they&#8217;ve <a href="http://www.think-box.co.uk/blog/2008/05/simplified-planning-board.html">revamped their planning board</a>. I found it to be an interesting read because for once someone else&#8217;s board looks similar to ours. </p>
<p>Our board has undergone a few makeovers as well over the past couple of years. In the beginning we tried to do what everyone else was doing. We had a big board with several columns. But our shop was small (at it&#8217;s peak, three developers and a PM) and the extra columns seemed wasteful. We didn&#8217;t really have a QA team, for instance, because we <em>were </em>the QA team. A &#8220;Testing&#8221; column seemed like a waste because we practice TDD as much as possible, so testing is part of the process of development. Same goes for acceptance tests, hands-on testing and customer approval. It&#8217;s all part of the process of developing software. Personally, I don&#8217;t look at the different elements - like architecture, design, testing or customer feedback - as separate phases. I see them as the one thing: developing software. They are all necessary elements to reach the final goal of a completed, working, and <em>trusted </em>software feature. </p>
<p>In the end, we finally settled on was <a href="http://en.wikiquote.org/wiki/Ward_Cunningham#The_Simplest_Thing_that_Could_Possibly_Work">the simplest thing that could possibly work</a>: Backlog, In Development &#038; Done. </p>
<p>Our <strong>Backlog </strong>is every story card in our possession. We don&#8217;t categorize; we just let the customer prioritize. <strong>In Development</strong> is everything we&#8217;re working on during this iteration. Since we - the developers - do it all, then <strong>In Development</strong> carries a comprehensive meaning. And when all the bases are covered, regardless of what order they were performed (although I hope unit tests were written <em>before </em>the code was) then, and only then, does it move to <strong>Done</strong>. </p>
<p>What I enjoy most about our board is that it is so simple to read. It&#8217;s easy to determine what&#8217;s left to do (Backlog), what&#8217;s being worked on (In Development) and what&#8217;s ready for the next publish at the end of the iteration (Done). And I don&#8217;t need to worry about testing or customer approval because those elements of the development process are implied. </p>
]]></content:encoded>
			<wfw:commentRSS>http://www.chrisholmesonline.com/2008/05/19/backlog-in-development-done/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Funny Because It&#8217;s True</title>
		<link>http://www.chrisholmesonline.com/2008/05/13/funny-because-its-true/</link>
		<comments>http://www.chrisholmesonline.com/2008/05/13/funny-because-its-true/#comments</comments>
		<pubDate>Wed, 14 May 2008 04:07:06 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
	<category>General</category>
	<category>Software Development</category>
		<guid isPermaLink="false">http://www.chrisholmesonline.com/2008/05/13/funny-because-its-true/</guid>
		<description><![CDATA[Jeff Atwood&#8217;s Coding Horror blog is one of the best on the internet. If you&#8217;re a software geek, developer, techie, or anything close, you have to put his feed in your aggregator. 
Recently, Jeff made a post about DRM-Free Music. Like all his posts, it&#8217;s a great read. But that&#8217;s not what I wanted to [...]]]></description>
			<content:encoded><![CDATA[<p>Jeff Atwood&#8217;s <a href="http://www.codinghorror.com/blog/">Coding Horror</a> blog is one of the best on the internet. If you&#8217;re a software geek, developer, techie, or anything close, you have to put his feed in your aggregator. </p>
<p>Recently, Jeff made a post about <a href="http://www.codinghorror.com/blog/archives/001113.html">DRM-Free Music</a>. Like all his posts, it&#8217;s a great read. But that&#8217;s not what I wanted to write about. </p>
<p>What I wanted to mention was this nugget from Jeff that had me laughing: </p>
<blockquote><p>
I&#8217;m sure that the moment man discovered fire, there was some guy nearby saying, &#8220;Too smoky. Can burn you. Lame.&#8221;
</p></blockquote>
<p>I laughed because, regardless of context, this is so true. There are people in this world who can manage to see the negative in everything. And from now on, when I run into those people, I&#8217;m going to recall this phrase that has stuck in my head. </p>
<p>And I&#8217;m going to smile <img src='http://www.chrisholmesonline.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Thanks Jeff. </p>
]]></content:encoded>
			<wfw:commentRSS>http://www.chrisholmesonline.com/2008/05/13/funny-because-its-true/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>We&#8217;re Hiring</title>
		<link>http://www.chrisholmesonline.com/2008/04/16/were-hiring/</link>
		<comments>http://www.chrisholmesonline.com/2008/04/16/were-hiring/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 06:23:58 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
	<category>.NET</category>
	<category>General</category>
	<category>Agile Development</category>
	<category>Software Development</category>
	<category>CAB</category>
		<guid isPermaLink="false">http://www.chrisholmesonline.com/2008/04/16/were-hiring/</guid>
		<description><![CDATA[For a while now, my employer has maintained an opening for a talented software developer. They have not advertised the position very heavily because (a) we live in an area that is not rich with developers and (b) our small, Agile team has chugged along fairly well without this extra person. 
That all changed today [...]]]></description>
			<content:encoded><![CDATA[<p>For a while now, my employer has maintained an opening for a talented software developer. They have not advertised the position very heavily because (a) we live in an area that is not rich with developers and (b) our small, Agile team has chugged along fairly well without this extra person. </p>
<p>That all changed today when a colleague - and friend - opted for greener pastures. He&#8217;s returning to the company where he started his career as an intern, a place he is particularly fond of, and I cannot blame him for taking a job that more closely fulfills his professional and personal desires. I wish him all the best. </p>
<p>Still, our small team of developers just shrunk by one, and we need to fill the gap. </p>
<p>In a larger city this would not be a problem. We&#8217;d just advertise the position and the resumes would pour in. But our location is our biggest hurdle when it comes to attracting talented developers. We simply can&#8217;t pull from as large a pool as a city like Austin, Texas can. </p>
<p>So where do I work? <a href="http://www.co.nezperce.id.us/">Nez Perce County</a>, a small county government in north-central Idaho. As one might imagine, it is not exactly a mecca for software development talent. But that hasn&#8217;t stopped us from trying. People we talk to are always surprised to learn that our tiny little IT shop in Idaho is practicing Agile techniques. Yet that is exactly what we&#8217;re doing. </p>
<p>We subscribe to <a href="http://en.wikipedia.org/wiki/Agile_software_development">Agile </a>practices, <a href="http://en.wikipedia.org/wiki/Extreme_Programming">Extreme Programming</a> in particular, and we drink from the <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD </a>fountain. We use <a href="http://en.wikipedia.org/wiki/Continuous_Integration">Continuous Integration</a>, unit tests, acceptance tests, and frequent customer feedback along with short iterations to write quality, maintainable code and deliver business value to our customers (which, incidentally, includes us, since we are also taxpayers; we&#8217;re our own bosses in manner of speaking). </p>
<p>We work in an open environment and every developer has two monitors at their workstation. We work closely together as a team and have an on-site customer to help provide rapid feedback. </p>
<p><strong>What We&#8217;re Looking For</strong></p>
<p>We realize that we&#8217;re a bit handicapped by our geography. We&#8217;re not going to see a lot of great resumes. So it&#8217;s important for us to identify candidates that have the capacity to <em>learn </em> and possess a passion for software development. Ideally, candidates for our shop would have the following qualifications: </p>
<ul>
<li>Knowledge of Object Oriented design and principles</li>
<li>Knowledge/Experience with C# .Net, or a similar object-oriented language (Java, C++)</li>
<li>Database experience</li>
<li>Willingness to learn</li>
</ul>
<p>Bonus points for knowledge/experience with any of the following: Gang of Four design patterns, Unit Testing, IoC, CAB and/or SQL Server.</p>
<p>More information about the position, including benefits and pay, can be gathered by contacting my boss, <strong>Randy Buttenhoff</strong>, via the <a href="http://www.co.nezperce.id.us/infosy/Commissioners/InformationSystems/tabid/270/Default.aspx">Nez Perce County IT web page.</a> </p>
]]></content:encoded>
			<wfw:commentRSS>http://www.chrisholmesonline.com/2008/04/16/were-hiring/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Unsaved Changes When CAB Application Closes: The Notification Pattern</title>
		<link>http://www.chrisholmesonline.com/2008/04/10/unsaved-changes-when-cab-application-closes-the-notification-pattern/</link>
		<comments>http://www.chrisholmesonline.com/2008/04/10/unsaved-changes-when-cab-application-closes-the-notification-pattern/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 03:21:30 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
	<category>.NET</category>
	<category>Software Development</category>
	<category>CAB</category>
		<guid isPermaLink="false">http://www.chrisholmesonline.com/2008/04/10/unsaved-changes-when-cab-application-closes-the-notification-pattern/</guid>
		<description><![CDATA[Occasionally this question pops up on the CAB message boards: How do I prevent my application from closing if the user has unsaved changes? 
Turns out that there&#8217;s a very simple pattern you can utilize to handle this situation. It&#8217;s called the Notification Pattern. Jeremy Miller, .Net guru, has a very good blog post on [...]]]></description>
			<content:encoded><![CDATA[<p>Occasionally this question pops up on the <a href="http://www.codeplex.com/smartclient/Thread/List.aspx">CAB message boards</a>: How do I prevent my application from closing if the user has unsaved changes? </p>
<p>Turns out that there&#8217;s a very simple pattern you can utilize to handle this situation. It&#8217;s called the <a href="http://martinfowler.com/eaaDev/Notification.html">Notification Pattern</a>. Jeremy Miller, .Net guru, has a <a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern.aspx">very good blog post on this pattern</a>. He uses it to illustrate a standard way to handle validation on domain objects, but it&#8217;s a valuable pattern in other cases too, as I&#8217;ll show. </p>
<p>As <a href="http://martinfowler.com/eaaDev/Notification.html">Martin Fowler</a> writes in his article, the Notification Pattern can be as simple as &#8220;a collection of strings which are error messages that the domain generates while it&#8217;s doing its work.&#8221;  This is, in fact, how simple our implementation is where I work. A collection of strings, nothing more. You can use something else besides strings - a rich object with many properties and a public interface - if you like. But for this demonstration I&#8217;ll stick to strings. </p>
<p>The easiest way to implement this in CAB is with a Service class. All that is required is an event and a method to call to get notifications. The interface to the service basically looks like this: </p>
<pre>
<code>public delegate void ApplicationClosingEventHandler(List&lt;string&gt; notifications);

public interface INotificationService
{
   event ApplicationClosingEventHandler ApplicationClosing;
   List&lt;string&gt; GetNotifications();
}</code>
</pre>
<p>And the Service itself: </p>
<pre>
<code>
public class NotificationService : INotificationService
{
   public virtual event ApplicationClosingEventHandler ApplicationClosing;

   public virtual List&lt;string&gt; GetNotifications()
   {
      List&lt;string&gt; notifications = new List&lt;string&gt;();

      if (ApplicationClosing != null)
      {
         foreach (ApplicationClosingEventHandler handler in ApplicationClosing.GetInvocationList())
         {
            handler.Invoke(_unsavedChangesNotifications);
         }
      }
      return notifications ;
   }
}</code>
</pre>
<p>WorkItems, Presenters and other classes that know about the dirty state of their models can take a dependency on this Service and subscribe to the ApplicationClosing event. When the event is fired, their handler adds a notification to the list, if it needs to. </p>
<pre>
<code>
public MyPresenter : Presenter&lt;IMyView&gt;
{
   private INotificationService _notificationService; 

   public MyPresenter([ServiceDependency] INotificationService notificationService)
   {
      _notificationService = notificationService;
      _notificationService.ApplicationClosing += new ApplicationClosingEventHandler(AppClosingHandler);
   }

   private void AppClosingHandler(List&lt;string&gt; notifications)
   {
      if(myModelIsDirty)
         notifications.Add("My object is dirty");
   }
}</code>
</pre>
<p>The next step is to hook the whole thing into the Shell.Closing event. Back in the ShellApplication class, typically in the AfterShellCreated override, you can wire up to the Shell.Closing event: </p>
<pre>
<code>public override AfterShellCreated()
{
   base.AfterShellCreated();

   Shell.Closing += new CancelEventHandler(Shell_Closing);
}</code>
</pre>
<p>In your handler, you can query the INotificationService and get any notifications. If the notification list is empty, you can safely exit the application. Otherwise, pop a MessageBox and alert them. </p>
<pre>
<code>private void Shell_Closing(object sender, CancelEventArgs ee)
{
   INotificationService notificationService = RootWorkItem.Services.Get&lt;INotificationService&gt;();

   List&lt;string&gt; notifications = notificationService.GetNotifications();

   if(notifications.Count &gt; 0)
   {
      e.Cancel = true;
      // Alert the user
   }
}</code>
</pre>
<p>That&#8217;s it. Simple, right? The nice thing about this pattern is that even with simple notifications, like strings, you can still give the user some very useful information on where unsaved changes exist. In our application, for instance, we let the user know which module and &#8220;use case&#8221; (very broad term here) contains the unsaved changes, so they can find those unsaved changes faster and make the save. </p>
<p>The Notification Pattern is one of the simplest, yet most useful, patterns that you&#8217;ll run into in any application, not just CAB. Now go forth and prevent your users from losing data when they close your app!
</p>
]]></content:encoded>
			<wfw:commentRSS>http://www.chrisholmesonline.com/2008/04/10/unsaved-changes-when-cab-application-closes-the-notification-pattern/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>The Ruins</title>
		<link>http://www.chrisholmesonline.com/2008/04/06/the-ruins/</link>
		<comments>http://www.chrisholmesonline.com/2008/04/06/the-ruins/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 02:52:42 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
	<category>Movies</category>
		<guid isPermaLink="false">http://www.chrisholmesonline.com/2008/04/06/the-ruins/</guid>
		<description><![CDATA[


&#8220;So what do you guys think: Ancient Mayan temple off the beaten path?&#8221; - Jeff
Conventional wisdom says the beaten path exists for a reason: it&#8217;s safe. But conventional wisdom isn&#8217;t much of a match for a group of young travelers who wish to avoid &#8220;tourist traps&#8221; while on vacation. And so, with little reservation, best [...]]]></description>
			<content:encoded><![CDATA[<p>
<img src="http://www.chrisholmesonline.com/images/The_Ruins.jpg" alt="The Ruins" style="float: right; padding-left: 15px; padding-bottom: 20px;"/>
</p>
<p>&#8220;So what do you guys think: Ancient Mayan temple off the beaten path?&#8221; - Jeff</p>
<p>Conventional wisdom says the beaten path exists for a reason: it&#8217;s safe. But conventional wisdom isn&#8217;t much of a match for a group of young travelers who wish to avoid &#8220;tourist traps&#8221; while on vacation. And so, with little reservation, best friends Amy (Jena Malone) and Stacy (Laura Ramsey) head off to an ancient Mayan temple at the urging of their boyfriends, Jeff (Jonathan Tucker) and Eric (Shawn Ashmore). </p>
<p>The group has been intrigued by a foreigner named Mathias whose brother, Henrich, has gone to the temple with his archaeologist girlfriend. Neither has returned, but Mathias quips that it&#8217;s probably because they&#8217;re having so much &#8220;fun&#8221;. At an old Mayan Temple. In the middle of nowhere. </p>
<p>Queue scary music here. </p>
<p>Amy gets cold feet when the group comes to an apparent dead end, only to find that the trail has been concealed with bushes. A couple of silent, young children show up several yards away in a creek bed to manufacture tension because apparently young children are scary. Amy&#8217;s intuition is to turn around and go back to the cushy confines of the hotel and pool. Why her boyfriend Jeff prefers visit dusty old ruins instead of jumping her bones at the hotel is a mystery.</p>
<p>No sooner does the group arrive at the foot of the ruins than some gruff looking &#8220;natives&#8221; arrive, complete with horses, guns, bows and arrows. They seem very threatening from the word &#8220;go.&#8221; A language barrier prevents either side from being able to explain themselves, and soon thereafter things turn bad. Pretty soon the tourists find themselves atop the ruins, unable to leave thanks to the folks with bows and guns. </p>
<p>To reveal what happens next would spoil the surprise of &#8220;The Ruins.&#8221; It is sufficient to say that it is probably what you did <em>not </em>see coming. In a way, &#8220;The Ruins&#8221; can thank recent horror films like &#8220;The Descent&#8221; and &#8220;28 Days Later&#8221; for priming its audience. Viewers will likely enter &#8220;The Ruins&#8221; thinking they have an idea of what to expect. They will be wrong. </p>
<p>Like &#8220;The Descent&#8221;, &#8220;The Ruins&#8221; doesn&#8217;t play any dirty tricks with its audience. It stays faithful to the rules it establishes early on. But unlike &#8220;The Descent&#8221;, the film only works because of a bit of manufactured drama, namely, the &#8220;natives&#8221;, who serve to keep the tourists trapped in their predicament. The film justifies this mechanism logically, but even so it still feels forced and mechanical, and detracts from the overall quality of the movie. </p>
<p>Still, &#8220;The Ruins&#8221; works. It achieves what it sets out to achieve and does so with a fairly creative horror device. It&#8217;s not as good as &#8220;The Descent&#8221; or &#8220;28 Days Later&#8221;, but it deserves a seat at the table. </p>
]]></content:encoded>
			<wfw:commentRSS>http://www.chrisholmesonline.com/2008/04/06/the-ruins/feed/</wfw:commentRSS>
		</item>
	</channel>
</rss>
