<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Tim Barcz</title><link>http://devlicio.us/blogs/tim_barcz/default.aspx</link><description>Why use nails when a screw is the more reversible choice?  Have Twitter, follow the conversation there at @&lt;a href="http://www.twitter.com/timbarcz"&gt;timbarcz&lt;/a&gt;</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/TimBarcz" type="application/rss+xml" /><item><title>The "Risk" of Open Source Software Support</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/Zloa1KX2m0Y/the-quot-risk-quot-of-open-source-software-support.aspx</link><pubDate>Tue, 30 Jun 2009 03:18:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:48827</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>13</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=48827</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/06/29/the-quot-risk-quot-of-open-source-software-support.aspx#comments</comments><description>&lt;p&gt;Quite often there is a fear that surrounds open source tools and frameworks.&amp;nbsp; For most shops the deciding factor against open source software is the apparent &amp;quot;risk&amp;quot; that is associated with a framework/tool that is not attached to any business entity.&lt;/p&gt;
&lt;p&gt;In this post I want to share an interaction that occurred this last weekend to show you that the open source ecosystem is alive and very healthy.&amp;nbsp; And while I won&amp;#39;t go so far as to say the &amp;quot;risk&amp;quot; doesn&amp;#39;t exist (you have to come to that conclusion on your time when your own fears are allayed) I do hope that this post puts some of those fears to rest.&lt;/p&gt;
&lt;p&gt;Saturday morning before I went off to work there was a question posted to the &lt;a href="http://groups.google.com/group/RhinoMocks/"&gt;RhinoMocks mailing list&lt;/a&gt; (for those who don&amp;#39;t know &lt;a href="http://ayende.com/projects/rhino-mocks.aspx"&gt;RhinoMocks&lt;/a&gt; is an open source mocking framework).&amp;nbsp; Before the end of the day the problem was resolved to a satisfactory conclusion.&amp;nbsp; The &amp;quot;solution&amp;quot; (I put in quotes because there appears to be a bug but at least now we know there is a bug...hence &amp;quot;solution&amp;quot;).&amp;nbsp; The result is not as important as the events that transpired to reach that conclusion below is the timeline.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;12:22 AM - Kenneth posts the problem he is encountering&lt;/p&gt;
&lt;p&gt;6:53 AM - I respond on the mailing list back to Kenneth with my findings and let him know that I will get some experts in DynamicProxy involved&lt;/p&gt;
&lt;p&gt;6:56 AM - &lt;a href="http://twitter.com/TimBarcz/status/2358015264"&gt;I enlisted the help of Krzysztof Kozmic on twitter&lt;/a&gt; (&lt;a href="http://kozmic.pl/"&gt;Krzysztof&lt;/a&gt; is a committer on &lt;a href="http://www.castleproject.org/dynamicproxy/index.html"&gt;DynamicProxy by Castle&lt;/a&gt; as has a &lt;a href="http://kozmic.pl/archive/2009/04/27/castle-dynamic-proxy-tutorial.aspx"&gt;great tutorial series on Dynamic Proxy&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;8:38 AM - Fellow &lt;a href="http://devlicio.us/blogs/tuna_toksoz/"&gt;Devlicious blogger Tuna Toksoz&lt;/a&gt; (also a committer on the Castle project) hopped on the case and reported his findings&lt;/p&gt;
&lt;p&gt;9:22 AM - Krzysztof responds to Tuna&amp;#39;s findings reporting back on the root cause&lt;/p&gt;
&lt;p&gt;10:23 AM - Kenneth reported back with feedback of Tuna&amp;#39;s fix&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ultimately, as I mentioned earlier the fix was that it was found that RhinoMocks &amp;quot;relies on the buggy behavior, hence the error&amp;quot; (Krzysztof&amp;#39;s words).&amp;nbsp; Again the result here isn&amp;#39;t what is important but rather the journey.&amp;nbsp; Often people fear the support ecosystem around open source software but the exchange above and the players involved should give you some bit of confidence in the support of open source.&amp;nbsp; It is worth pointing out that all of this happened on a Saturday, something you&amp;#39;d pay a premium for in a closed source model.&lt;/p&gt;
&lt;p&gt;Whatever your roll in the software world is, one aspect you have to consider when choosing any solution is risk.&amp;nbsp; The traditional thought has been that with commercial software the support would be better when backed by a reputable name.&amp;nbsp; I think the exchange showcased above demonstrates that support for open source software can compete (and potentially surpass) support that any commercial piece of software could offer.&amp;nbsp; Keep that in mind the next time you are evaluating commercial software versus open source software.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=48827" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/Zloa1KX2m0Y" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Open+Source+Software/default.aspx">Open Source Software</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Project+Management/default.aspx">Project Management</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/06/29/the-quot-risk-quot-of-open-source-software-support.aspx</feedburner:origLink></item><item><title>The Holy Grail is NOT Automation</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/GIPMlRqOm-Q/the-holy-grail-is-not-automation.aspx</link><pubDate>Fri, 29 May 2009 02:05:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:47293</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>21</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=47293</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/05/28/the-holy-grail-is-not-automation.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image_5F00_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image_5F00_thumb.png" align="right" border="0" width="240" height="211" /&gt;&lt;/a&gt; Often times as developers who understand what computers can do is really limitless, we seek to automate everything.&amp;nbsp; The holy grail is being able to sit at where everything is accomplishable with a simple double-click. Often times automation, however wonderful or geek drool inspiring, is not cost effective.&lt;/p&gt;
&lt;p&gt;Once a month we have to update sales tax rates in our system.&amp;nbsp; We have a program that does the update but needs two vital pieces of information which are supplied to us a few days before the end of the month via an email.&amp;nbsp; These two pieces of information are a download file location and a password.&amp;nbsp; We enter the two pieces of information as command line args to the program and off we go.&amp;nbsp; The whole process takes about a minute.&lt;/p&gt;
&lt;p&gt;While running the update today there was a brief discussion about how we could possibly automate the whole process.&amp;nbsp; Ideas floated around like reading the email and parsing the text for the download location and the password.&amp;nbsp; In order to do this we&amp;#39;d have to write an program which:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can connect to our Exchange server or a mailbox on our system&lt;/li&gt;
&lt;li&gt;Scan the inbox for the particular message you are looking for&lt;/li&gt;
&lt;li&gt;Parse out the two pieces of information from the email&lt;/li&gt;
&lt;li&gt;Launch the original program passing in the two pieces of information we just gathered&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;#39;s say for a moment that you&amp;#39;re a good programmer. I mean &lt;a href="http://www.ayende.com/blog"&gt;ayende&lt;/a&gt; good.&amp;nbsp; How long does it take you to write this? An hour? Two?&amp;nbsp; Ten? A week (40)?&amp;nbsp; Let&amp;#39;s be real aggressive developers here with over-inflated sense of skill for a moment and say we can do this and have it production ready in an hour.&amp;nbsp; If it takes us a minute to run by hand, then &lt;b&gt;it will take us 5 years to get a return on the investment&lt;/b&gt; we put into the project.&amp;nbsp; If we&amp;#39;re more down to earth and estimate the project takes 10 hours, we &lt;b&gt;will absolutely never see a return on that time spent because your application which needs the tax information will be rewritten, trashed, or abandoned long before the 50 years it would take to start seeing a return.&amp;nbsp; &lt;/b&gt;I was glad to hear it when my fellow developers came to this conclusion as well.&amp;nbsp; Automation is great to a point when it saves time.&amp;nbsp; Any effort beyond that is hard to justify and could be seen as wasteful.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=47293" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/GIPMlRqOm-Q" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Rant/default.aspx">Rant</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Opinion/default.aspx">Opinion</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/05/28/the-holy-grail-is-not-automation.aspx</feedburner:origLink></item><item><title>Regular Expressions, Your Job Requires Them</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/JAhCwYGFkIE/regular-expressions-your-job-requires-them.aspx</link><pubDate>Tue, 26 May 2009 02:18:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:47138</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>21</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=47138</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/05/25/regular-expressions-your-job-requires-them.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/RegularExpressionLearnthem_8736/image_9.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/RegularExpressionLearnthem_8736/image_thumb_3.png" width="321" align="right" border="0" height="520" /&gt;&lt;/a&gt;In preparing my talk on Regular Expressions that I&amp;#39;ll be giving this upcoming weekend at the &lt;a href="http://www.chicagocodecamp.com"&gt;Chicago Code Camp&lt;/a&gt; I decided to repost this article which I originally posted in February of last year.&amp;nbsp; Rereading the information contained within my position or thoughts on developers and regular expression have not changed.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve thought about writing this post several times over the past two years.&amp;nbsp; Having had regular expressions come up three times last week, I thought it time to address the lack of programmers out there who understand regular expressions.&amp;nbsp; The sheer amount of fear surrounding regular expressions and the work that goes into avoiding them is astonishing.&lt;/p&gt;
&lt;p&gt;Last year I used to troll around the &lt;a href="http://www.asp.net/forums/"&gt;asp.net forums&lt;/a&gt; and quite frequently I would answer the regex questions.&amp;nbsp; One &lt;a href="http://forums.asp.net/t/1125123.aspx"&gt;question was posted&lt;/a&gt; which illustrates the problem with regexes among developers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;...and i also i need to add a validator for the password textbox where the user is required to fill atleast [sic] 6 characters&amp;quot; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I suggested a solution to the problem using a regular expression validator. Making sure there are at least 6 characters, is a simple regex (example: \w{6,}), and yet my solution was met with skepticism.&amp;nbsp; The following was said, in the event a change was requested, &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Putting a new version of a web site can take a surprising amount of time than can go into man-weeks&amp;quot;.&amp;nbsp; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Man-weeks?!?!?&amp;nbsp; To change a regular expression?!?!?&amp;nbsp; I see two problems, first the original developer who didn&amp;#39;t know that regex would easily solve their problem.&amp;nbsp; The second problem is the other developer who doesn&amp;#39;t know regex advocating his way as &amp;quot;the way&amp;quot;, in effect, spreading his ignorance.&amp;nbsp; The first developer is easily forgiven, the second is not.&lt;/p&gt;
&lt;p&gt;It&amp;#39;s been said &lt;a href="http://www.codinghorror.com/blog/archives/000781.html"&gt;programmers can&amp;#39;t program&lt;/a&gt; when faced with a simple FizzBuzz test, &lt;a href="http://tickletux.wordpress.com/"&gt;Imran&lt;/a&gt; states:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Want to know something scary? - the majority of comp sci graduates can&amp;rsquo;t. I&amp;rsquo;ve also seen self-proclaimed senior programmers take more than 10-15 minutes to write a solution.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&amp;#39;ll pile on.&amp;nbsp; &lt;b&gt;You want to know something scary?&amp;nbsp; The majority of professional programmers can&amp;#39;t write regular expressions, even simple ones&lt;/b&gt;.&amp;nbsp; I&amp;#39;m not the first to say this.&amp;nbsp; Last year, at the &lt;a href="http://altdotnet.org/"&gt;ALT.NET&lt;/a&gt; conference, &lt;a href="http://weblogs.asp.net/scottgu/"&gt;Scott Guthrie&lt;/a&gt; made the following statement when talking about routes in the new MVC framework:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;It&amp;#39;s pluggable, so you can use Regexes...&amp;lt;some incoherent stuff&amp;gt;...if you wanna use regexes you can.&amp;nbsp; What we found is, regexes are super powerful, but only about 10% of people actually understand &amp;#39;em.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Are regular expressions easy to understand? Well, let me ask you, was HTML easy when you started?&amp;nbsp; Were you born understanding the following HTML?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family:Courier;font-size:x-small;"&gt;&amp;lt;fieldset class=&amp;quot;CheckRadio&amp;quot;&amp;gt;        &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div id=&amp;quot;OngoingEventContainer&amp;quot;&amp;gt;         &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;input type=&amp;quot;checkbox&amp;quot; id=&amp;quot;OngoingEvent&amp;quot; name=&amp;quot;OngoingEvent&amp;quot; value=&amp;quot;1&amp;quot; /&amp;gt;         &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;label for=&amp;quot;OngoingEvent&amp;quot;&amp;gt;         &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; This is an ongoing event (no dates and times)         &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/label&amp;gt;         &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;         &lt;br /&gt;&amp;lt;/fieldset&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you understand the above, you didn&amp;#39;t always.&amp;nbsp; My guess is that at some point you buckled down and learned HTML because you&amp;#39;re job requires it.&amp;nbsp; Well, if you&amp;#39;re a programmer, web or windows, &lt;b&gt;you need to know regular expressions, your job requires it, it&amp;#39;s that simple.&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/RegularExpressionLearnthem_8736/image_7.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="image" src="http://www.timbarcz.com/blog/content/binary/WindowsLiveWriter/RegularExpressionLearnthem_8736/image_thumb_2.png" width="344" align="right" border="0" height="325" /&gt;&lt;/a&gt;Regular expressions have been around so long that they&amp;#39;re deeply ingrained in many of the tools we use.&amp;nbsp; &lt;a href="http://devlicious.com/blogs/christopher_bennage"&gt;Christopher Bennage&lt;/a&gt; illustrates how regular expressions solved a recent problems in Visual Studio.&amp;nbsp; In a &lt;a href="http://devlicious.com/blogs/christopher_bennage/archive/2008/02/21/discovering-empty-try-catch-blocks.aspx"&gt;recent post&lt;/a&gt; he posts:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Then I realized that I was missing the simple solution. Ctrl+F and a regular expression!&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don&amp;#39;t know that many people would be able to come to the conclusion that Christoper did.&amp;nbsp; It&amp;#39;s my belief that regular expressions are fundamental, yet the average developer doesn&amp;#39;t treat them as such.&amp;nbsp; They&amp;#39;re ultimately doing themselves a disservice.&lt;/p&gt;
&lt;p&gt;Regular Expressions are a tool that should be in every programmers bag.&amp;nbsp; If you don&amp;#39;t understand regular expressions and do a google search every time you need a regular expression, shame on you!&amp;nbsp; It&amp;#39;s time to bite the bullet and learn regular expressions.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=47138" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/JAhCwYGFkIE" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Rant/default.aspx">Rant</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Regular+Expressions/default.aspx">Regular Expressions</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/05/25/regular-expressions-your-job-requires-them.aspx</feedburner:origLink></item><item><title>Iowa Code Camp v. 3.0</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/8kNMASlnOAU/iowa-code-camp-v-3-0.aspx</link><pubDate>Fri, 10 Apr 2009 03:52:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:45788</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=45788</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/04/09/iowa-code-camp-v-3-0.aspx#comments</comments><description>&lt;p&gt;After two successful iterations of the &lt;a href="http://www.iowacodecamp.com"&gt;Iowa Code Camp&lt;/a&gt; it only seems fitting to have a third.&amp;#160; This third version will held &lt;strong&gt;May 2nd in &lt;/strong&gt;&lt;a href="http://maps.google.com/maps?q=cedar+rapids+Iowa&amp;amp;oe=utf-8&amp;amp;client=firefox-a&amp;amp;ie=UTF8&amp;amp;split=0&amp;amp;gl=us&amp;amp;ei=5r7eSdjhC-HonQentaSwCQ&amp;amp;z=11&amp;amp;iwloc=A"&gt;&lt;strong&gt;Cedar Rapids, Iowa&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; at &lt;/strong&gt;&lt;a href="http://www.kirkwood.cc.ia.us/"&gt;&lt;strong&gt;Kirkwood Community College&lt;/strong&gt;&lt;/a&gt; continuing the trend that Iowa Code Camp will move to serve its constituents all over the state.&amp;#160; I&amp;#39;d like to thank my former employer &lt;a href="http://www.geonetric.com"&gt;Geonetric&lt;/a&gt; for coming through in the clutch and helping out with securing/sponsoring a great location.&lt;/p&gt;  &lt;p&gt;I want to echo the call for speakers that fellow coordinator &lt;a href="http://www.solidrockstable.com/blogs/PragmaticTSQL/"&gt;Greg Wilson&lt;/a&gt; recently put out:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;i&gt;NOTE:&amp;#160; I do apologize that due to logistical issues with securing the location and date this call for speakers is coming much later than normal.&amp;#160; We, as leaders, have been working since early January on several possible locations/dates and just received confirmation on the final facility yesterday.&amp;#160; Please help us in getting the word out to as many potential speakers as possible as fast as possible. &lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;Topic ideas:&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;We are looking for 4 basic types of sessions: &lt;/p&gt;    &lt;p&gt;1)&amp;#160; We are welcoming non-.NET centric topics.&amp;#160; Hopefully, we can have another full track of &amp;quot;alternative&amp;quot; stuff.&amp;#160; Java, &amp;#39;nix, Mac, Drupal, open source, etc. &lt;/p&gt;    &lt;p&gt;2)&amp;#160; Beginning 100-level sessions targeted towards students and/or developers from another technology.&amp;#160; Things like:&amp;#160; LAMP Programming 101, Getting started in the .NET world, What college doesn&amp;#39;t teach you, Developing Java with Eclipse 101, User Interfaces 101 &lt;/p&gt;    &lt;p&gt;3)&amp;#160; Nice, meaty .NET sessions - The core of any code camp &lt;/p&gt;    &lt;p&gt;4)&amp;#160; Audience driven sessions.&amp;#160; We are planning to have various format sessions of experts that the community can ask questions to.&amp;#160;&amp;#160; We need volunteers to be in the sessions as &amp;quot;experts&amp;quot;.&amp;#160; We have various discussion groups (fishbowl, open topics, etc.) and may try some 1 on 1 help-them-with-their-code type of stuff. &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;I (&lt;a href="mailto:greg@solidrockstable.com"&gt;greg@solidDONTSPAMMErockstable.com&lt;/a&gt;) need to know as soon as reasonable who is interested in speaking.&amp;#160; Please let me know if you are definite or tentative, and what you intend to speak on.&amp;#160; (Title/Description/Bio)&amp;#160; I will be making the final schedule of speakers and tracks in mid-April.&amp;#160; we already have more than 10 speakers committed, so please respond soon.&amp;#160; If we have more speakers than sessions, we will work (per topic) on a first come/first served basis. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Like most code camps this camp will be free to attendees.&amp;#160; It is through generous sponsorship from companies and vendors that make these code camps possible. If you are interested in sponsoring an aspect of the code camp please let me know ASAP and we can see what can be worked out.&lt;/p&gt;  &lt;p&gt;If you are within a few hours drive, I encourage you to attend. It should be a great day of learning and exploring together. I hope to meet some of the readers of this blog at the camp.&amp;#160; Enough talk, go &lt;a href="http://iowacodecamp.com/"&gt;register now&lt;/a&gt; before all the spots fill up.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=45788" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/8kNMASlnOAU" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Announcement/default.aspx">Announcement</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Code+Camps/default.aspx">Code Camps</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/04/09/iowa-code-camp-v-3-0.aspx</feedburner:origLink></item><item><title>Code Coverage - 100% Coverage and Still Failing</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/_LcAYOuAhps/code-coverage-100-coverage-and-still-failing.aspx</link><pubDate>Tue, 31 Mar 2009 17:15:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:45304</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>12</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=45304</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/03/31/code-coverage-100-coverage-and-still-failing.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://devlicio.us/blogs/casey/"&gt;Casey&lt;/a&gt; posted last year about &lt;a href="http://devlicio.us/blogs/casey/archive/2008/05/16/statistics-and-how-they-lie.aspx"&gt;statistics that lie&lt;/a&gt;.&amp;nbsp; In the post Casey gives an overview of Cyclomatic Complexity and some guidelines to aim for when reviewing the cyclomatic complexity of your methods.&amp;nbsp; There&amp;#39;s a gem in the comments post by &lt;a href="http://davybrion.com/blog/"&gt;Davy Brion&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Yeah, code coverage is such a terrible indicator... the only time it really means something is when it&amp;#39;s low... at least you can be sure that&amp;#39;s not good.&amp;nbsp; If it&amp;#39;s high, it doesn&amp;#39;t mean anything.&amp;nbsp; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To illustrate why 100% code coverage should not be your ultimate goal, I have provided the simple illustration below.&lt;/p&gt;
&lt;h3&gt;The System Under Test (SUT)&lt;/h3&gt;
&lt;p&gt;I have a very simple method, which returns the quotient of two numbers:&lt;/p&gt;
&lt;div&gt;
&lt;div style="border-style:none;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; SampleMethod(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; dividend, &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; divisor)&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; dividend / divisor;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;The Test&lt;/h3&gt;
&lt;div&gt;
&lt;div style="border-style:none;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; [Test]&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Sample()&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// Act&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;     var result = SampleMethod(8, 2);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// Assert&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt;     Console.WriteLine(result);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;     Assert.That(result, Is.EqualTo(4));&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;The Warm Fuzzy&lt;/h3&gt;
&lt;p&gt;Well would you look at that, I&amp;#39;m covered, 100%.&amp;nbsp; Time to ship this bad boy.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/clip_5F00_image002_5F00_2.jpg"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" alt="clip_image002" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/clip_5F00_image002_5F00_thumb.jpg" width="361" border="0" height="106" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;The Hammer Drops&lt;/h3&gt;
&lt;div&gt;
&lt;div style="border-style:none;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; [Test]&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Sample_zero_divisor()&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// Act&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;     var result = SampleMethod(8, 0); &lt;span style="color:#008000;"&gt;// will throw an exception&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;// Assert&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt;     Console.WriteLine(result);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;     Assert.That(result, Is.EqualTo(???));&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:#f4f4f4;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Produces an error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TestCase &amp;#39;Samples.CodeCoverage.Tests.Test.Sample_zero_divisor&amp;#39;
    &lt;br /&gt;failed: System.DivideByZeroException : Attempted to divide by zero.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Yes this is all a bit contrived, but it illustrates the point, 100% code coverage does not mean 100% tested. As demonstrated here, 100% coverage simply means all code paths have been visited.&amp;nbsp; As such we have to both code defensively and test defensively.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=45304" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/_LcAYOuAhps" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Testing/default.aspx">Testing</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/03/31/code-coverage-100-coverage-and-still-failing.aspx</feedburner:origLink></item><item><title>Your IoC Container Choice is Not a Feature of Your Application</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/zo5HI4L3kHE/your-ioc-container-choice-is-not-a-feature-of-your-application.aspx</link><pubDate>Mon, 30 Mar 2009 02:51:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:45231</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>16</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=45231</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/03/29/your-ioc-container-choice-is-not-a-feature-of-your-application.aspx#comments</comments><description>&lt;p&gt;I don&amp;#39;t want to be a wet blanket, but someone&amp;#39;s got to put a stop to the IoC love fest going on out there.&amp;nbsp; An Inversion of Control (IoC) container , for those of you were aren&amp;#39;t yet familiar, allows you to retrieve instances of objects at runtime.&amp;nbsp; A relatively common solution to a common problem. In the .NET world there is no lack of choices of IoC containers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.castleproject.org/container/index.html"&gt;Castle&amp;#39;s Winsdor/MicroKernel&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://structuremap.sourceforge.net/Default.htm"&gt;StructureMap&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/autofac/"&gt;AutoFac&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://ninject.org/"&gt;Ninject&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc468366.aspx"&gt;Unity&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://funq.codeplex.com/"&gt;Funq&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(I won&amp;#39;t go fully into IoC, but If you&amp;#39;d like more resource you can read &lt;a href="http://martinfowler.com/articles/injection.html"&gt;Martin Fowler&amp;#39;s article on the subject&lt;/a&gt; or post specific questions in the comments or contact me through.&amp;nbsp; Read on, there is value here in this post for you.)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Let me state clearly now, IoC containers are a means to an end and NOT a feature of your application.&lt;/b&gt; The goal is to have loosely coupled applications, IoC containers help get you there, but you can absolutely have a loosely coupled application without an IoC container (see the &lt;a href="http://www.dofactory.com/Patterns/Patterns.aspx"&gt;Gang of Four creational patterns&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Occasionally I&amp;#39;ll hear some comment about IoC and how great a certain container is or how an application would be so much better if another, sexier, container was used.&amp;nbsp; Here are some recent &lt;a href="http://www.twitter.com"&gt;tweets&lt;/a&gt; that illustrate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Man i love #StructureMap, always finding new things i can do, and have fun doing them &lt;/li&gt;
&lt;li&gt;really need to look at structuremap, but we&amp;#39;&amp;#39;ve invested a lot into castle with our own facilities/resolvers/etc &lt;/li&gt;
&lt;li&gt;Ninject is da bomb! &lt;/li&gt;
&lt;li&gt;Switched from Windsor MicroKernel to Ninject in 10KLOC project in &amp;lt; 1 hour by creating a little proxy. Now to complete the conversion. &lt;/li&gt;
&lt;li&gt;It is a talk on Castle Windsor so i guess Ninject will not do. &lt;/li&gt;
&lt;li&gt;Can&amp;#39;t imagine why somebody would use Ninject beside the fact that it&amp;#39;s PURE AND UTTER AWESOME. Yeah! Ninject FTW. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of the statements above are probably innocuous, but some rub me slightly the wrong way.&amp;nbsp; Specifically the two comments above about switching from one container to another. There are probably times when the choice of one container over another makes sense, but I would bet that these scenarios are the exception and not the rule.&lt;/p&gt;
&lt;p&gt;Choosing one container over another won&amp;#39;t make your application a success, the architecture, or lack there of, will have far more of a say on your application than will your container choice. As yoda might say, &amp;quot;The container you choose does not a good app make&amp;quot;. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=45231" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/zo5HI4L3kHE" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Rant/default.aspx">Rant</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Opinion/default.aspx">Opinion</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Windsor/default.aspx">Windsor</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Tools/default.aspx">Tools</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/03/29/your-ioc-container-choice-is-not-a-feature-of-your-application.aspx</feedburner:origLink></item><item><title>ALT.NET Bingo!</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/ne0QfUWbcMo/alt-net-bingo.aspx</link><pubDate>Mon, 23 Mar 2009 18:02:20 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:45102</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>6</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=45102</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/03/23/alt-net-bingo.aspx#comments</comments><description>&lt;p&gt;Inspired by &lt;a href="http://www.bullshitbingo.net/cards/bullshit/"&gt;Bullshit Bingo&lt;/a&gt; I&amp;#39;ve created &lt;a href="http://is.gd/oA0A"&gt;ALT.NET Bingo&lt;/a&gt; for you next ALT.NET conference, &lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt; conversation, or blog reading session.&amp;#160; It&amp;#39;s simple:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Get your card! &lt;a title="http://is.gd/oA0A" href="http://is.gd/oA0A"&gt;http://is.gd/oA0A&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Every time you hear a word, you mark it off.&amp;#160; If you get bingo you stand up and shout, &amp;quot;WATERFALL!!&amp;quot;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Happy playing!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=45102" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/ne0QfUWbcMo" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Humor/default.aspx">Humor</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Alt.NET/default.aspx">Alt.NET</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/03/23/alt-net-bingo.aspx</feedburner:origLink></item><item><title>Choosing A Mocking Framework</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/45-E4Tgbq-M/choosing-a-mocking-framework.aspx</link><pubDate>Fri, 20 Mar 2009 04:02:59 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:45061</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>21</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=45061</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/03/19/choosing-a-mocking-framework.aspx#comments</comments><description>&lt;p&gt;If you&amp;#39;re serious about testing before long you&amp;#39;ll bump into the need to do some mocking. You can of course chose to write your own mocks but that is hardly time effective or trivial.&amp;#160; More than likely you&amp;#39;ll want to use a framework, but how do you choose between the most popular options?&lt;/p&gt;  &lt;p&gt;There&amp;#39;s been some discussion on &lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt; between &lt;a href="http://www.twitter.com/timbarcz"&gt;myself&lt;/a&gt; and &lt;a href="http://www.clariusconsulting.net/blogs/kzu/"&gt;Daniel Cazzulino&lt;/a&gt; &lt;a href="http://www.twitter.com"&gt;(@kzu&lt;/a&gt;), the creator of &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; (pronounced &amp;quot;Mock-you&amp;quot; or just &amp;quot;Mock&amp;quot;), a newer and popular .NET mocking, about mocking frameworks and what goes into choosing a mocking framework.&amp;#160; Daniel and I share a passion in mocking and by extension testing.&amp;#160; As the creator of Moq, I hold him in very high regard.&lt;/p&gt;  &lt;p&gt;The discussion centered around some work that &lt;a href="http://codevanced.net/"&gt;Andrew Kazyrevich&lt;/a&gt; has been doing recently.&amp;#160; Andrew is &lt;a href="http://www.google.com/search?q=define%3Aardour"&gt;passionate&lt;/a&gt; about mocking.&amp;#160; As such he&amp;#39;s created an &lt;a href="http://code.google.com/p/mocking-frameworks-compare"&gt;open source project&lt;/a&gt; which compares the &amp;quot;big dawgs&amp;quot; of .NET mocking frameworks.&amp;#160; In his &lt;a href="http://codevanced.net/post/Mocking-Frameworks-Compare.aspx"&gt;introductory post&lt;/a&gt; he explains the intent, which is message I support and want to help spread:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I&amp;#39;ve started a small open source project. It provides a unified set of tests written against Moq, NMock2, Rhino Mocks and Typemock Isolator, so that you can easily compare the frameworks and make an informed decision when picking one up. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In Andrew&amp;#39;s &lt;a href="http://codevanced.net/post/To-kill-a-mockingbird.aspx"&gt;most recent post&lt;/a&gt; he compares the execution time of the various frameworks.&amp;#160; My response on the &lt;a href="http://groups.google.com/group/RhinoMocks/browse_thread/thread/2f3bfbe688d95ae0"&gt;RhinoMocks mailing list&lt;/a&gt; was terse but sincere:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Curious about speed in your tests, is the a first level concern when choosing a testing framework?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Daniel answered the question in a &lt;a href="http://twitter.com/kzu/status/1354114894"&gt;tweet&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;IMO, API design, usability and expressiveness is a much more valuable comparison. #moq is not optimized for runtime perf.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;To which &lt;a href="http://twitter.com/TimBarcz/statuses/1354369248"&gt;I responded&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I would also throw in documentation, discoverability, and community into your equation.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So, fine blog reader, I have a question for you.&amp;#160; If you are using a mocking framework, what are your first-level concerns when you chose your framework?&amp;#160; For those who have yet to utilize a framework, what will you base your decision on when you do choose?&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Execution Speed &lt;/li&gt;    &lt;li&gt;API Design &lt;/li&gt;    &lt;li&gt;Usability &lt;/li&gt;    &lt;li&gt;Expressiveness &lt;/li&gt;    &lt;li&gt;Documentation &lt;/li&gt;    &lt;li&gt;Discoverability (possibly coincides with API Design) &lt;/li&gt;    &lt;li&gt;Community &lt;/li&gt;    &lt;li&gt;Other? &lt;/li&gt; &lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=45061" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/45-E4Tgbq-M" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Testing/default.aspx">Testing</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Rhino+Mocks/default.aspx">Rhino Mocks</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Open+Source+Software/default.aspx">Open Source Software</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/03/19/choosing-a-mocking-framework.aspx</feedburner:origLink></item><item><title>Open Source Maturity Model Explored</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/jJmseRCNITM/open-source-maturity-model-revealed.aspx</link><pubDate>Tue, 17 Mar 2009 04:49:31 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:45003</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>12</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=45003</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/03/16/open-source-maturity-model-revealed.aspx#comments</comments><description>&lt;p&gt;About a month ago &lt;a href="http://www.ayende.com/blog"&gt;Ayende&lt;/a&gt; posted his thoughts on the &lt;a href="http://ayende.com/Blog/archive/2009/02/12/ayendes-open-source-project-maturity-model.aspx"&gt;Maturity Model found in Open Source Projects&lt;/a&gt;.&amp;#160; Ayende&amp;#39;s method for determining maturity is simple:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;From my point of view, there is a very easy model for the maturity of an Open Source project. Look at the &lt;em&gt;answers&lt;/em&gt; in the project&amp;#39;s mailing list. The questions do no matter.&lt;/p&gt;    &lt;p&gt;The model is simple, the higher the percentage of answers given by non project members, the more mature the project is.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I thought of this today when I came across the group info page for the &lt;a href="http://ayende.com/projects/rhino-mocks.aspx"&gt;RhinoMocks&lt;/a&gt; and saw the statistics for this month.&amp;#160; I was struck by how low on the list Ayende is:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image_5F00_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="265" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image_5F00_thumb.png" width="232" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;You can see here that Ayende is tied for #5 on the list.&amp;#160; (Yes that&amp;#39;s me on the list, but that&amp;#39;s beside the point.)&amp;#160; In two polls (&lt;a href="http://weblogs.asp.net/rosherove/archive/2007/04/26/choosing-a-mock-object-framework.aspx"&gt;poll #1&lt;/a&gt;, &lt;a href="http://weblogs.asp.net/rosherove/archive/2009/03/09/what-isolation-mocking-and-unit-testing-framework-are-you-using.aspx"&gt;poll #2&lt;/a&gt;) done over the last two years &lt;a href="http://weblogs.asp.net/rosherove/default.aspx"&gt;Roy Osherove&lt;/a&gt; has found RhinoMocks to be the #1 mocking framework of those polled.&amp;#160; I believe it is safe to say at this point that RhinoMocks is mature.&amp;#160; Measured with Ayende&amp;#39;s method above and the data for this month&amp;#39;s &lt;a href="http://groups.google.com/group/RhinoMocks/"&gt;RhinoMocks group&lt;/a&gt;, I&amp;#39;d say that RhinoMocks is quite mature.&amp;#160; Ayende, the project creator/owner, sits at #5, which is pretty good.&lt;/p&gt;  &lt;p&gt;Being familiar with open source I wanted to explore the maturity idea a bit further in depth on some other projects.&amp;#160; I posted on &lt;a href="http://www.twitter.com/timbarcz"&gt;twitter&lt;/a&gt; a question about what open source projects people are using.&amp;#160; I wanted to take a few projects that are out there and explore a little bit to see if Ayende&amp;#39;s assertion was in fact correct.&lt;/p&gt;  &lt;h2&gt;Other Projects&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;(Note: I am only exploring projects which have groups on Google.&amp;#160; These projects are in no particular order.)&lt;/strong&gt;&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;jQuery&lt;/h3&gt;  &lt;p&gt;Members: 15487&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image4.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="259" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image4_5F00_thumb.png" width="217" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(Note the absence of &lt;a href="http://ejohn.org/"&gt;John Resig&lt;/a&gt;)&lt;/p&gt;  &lt;h3&gt;Castle Project&lt;/h3&gt;  &lt;p&gt;Members: 795&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image8_5B00_1_5D00_.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="263" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image8_5B00_1_5D005F00_thumb.png" width="217" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(Note the absence of &lt;a href="http://hammett.castleproject.org/"&gt;Hamilton Verissimo&lt;/a&gt;)&lt;/p&gt;  &lt;h3&gt;NUnit&lt;/h3&gt;  &lt;p&gt;Members: 204&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image12.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="258" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image12_5F00_thumb.png" width="243" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(While I would rank NUnit as &amp;quot;mature&amp;quot; &lt;a href="http://www.charliepoole.org/cp.php"&gt;Charlie Poole&lt;/a&gt; is the top answerer, which does not match Ayende&amp;#39;s method)&lt;/p&gt;  &lt;h3&gt;MbUnit&lt;/h3&gt;  &lt;p&gt;Members: 353&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image16.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="197" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image16_5F00_thumb.png" width="175" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(The findings in NUnit are not isolated, &lt;a href="http://blog.bits-in-motion.com/"&gt;Jeff Brown&lt;/a&gt;, the MbUnit lead, is the top answerer)&lt;/p&gt;  &lt;h3&gt;NHibernate&lt;/h3&gt;  &lt;p&gt;Members: 1434&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image22.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="257" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image22_5F00_thumb.png" width="176" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(This is where I started to douby my original hypothesis.&amp;#160; I did not expect to see project owners so high up on the list for such a seemingly mature project.&amp;#160; However NHibernate has a learning curve to it that may hinder would-be helpers from ever getting to the point where they can confidently answer questions regularly on the framework.)&lt;/p&gt;  &lt;h3&gt;FluentNHibernate&lt;/h3&gt;  &lt;p&gt;Members: 301&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image19.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="265" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image19_5F00_thumb.png" width="196" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(Again project owner is top answer, by a long margin here).&lt;/p&gt;  &lt;h3&gt;StructureMap&lt;/h3&gt;  &lt;p&gt;Members: 209&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image27.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="257" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image27_5F00_thumb.png" width="212" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(This one again surprised me a bit, especially given the work that I know &lt;a href="http://codebetter.com/blogs/jeremy.miller/"&gt;Jeremy&lt;/a&gt; has done with documentation)&lt;/p&gt;  &lt;h3&gt;MvcContrib&lt;/h3&gt;  &lt;p&gt;Members: 302&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image31.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="254" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image31_5F00_thumb.png" width="204" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;TestDriven.NET&lt;/h3&gt;  &lt;p&gt;Member: 184&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image35.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="231" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image35_5F00_thumb.png" width="225" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(Owner and creator, &lt;a href="http://weblogs.asp.net/nunitaddin/"&gt;Jamie Cansdale&lt;/a&gt;, clearly the favorite)&lt;/p&gt;  &lt;h3&gt;Spark (Mvc View Engine)&lt;/h3&gt;  &lt;p&gt;Members: 83&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image5.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="277" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/tim_5F00_barcz/image5_5F00_thumb.png" width="189" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(Owner and creator, &lt;a href="http://whereslou.com/"&gt;Louis DeJardin&lt;/a&gt;, sits atop the #1 position)&lt;/p&gt;  &lt;h2&gt;Conclusion&lt;/h2&gt;  &lt;p&gt;When I started to dig, I wasn&amp;#39;t sure what I find.&amp;#160; In many cases here the project owner is sitting right at or near the top of the top answerer list. Still, I think Ayende&amp;#39;s original assertion is somewhat correct, however more has to be considered.&amp;#160; For example, a very well documented framework may lead to questions being asked that are rather difficult and therefore a larger number of questions answered by project founder may not really prove anything.&amp;#160; In other cases there may be a framework which is widely used but users don&amp;#39;t feel compelled or comfortable answering questions for that group, for any number of reasons.&amp;#160; Ultimately any notion of what presumed before exploration was blasted to bits.&lt;/p&gt;  &lt;p&gt;These projects above are not fringe projects, they&amp;#39;re relatively mainstream for a certain sector of the .NET crowd.&amp;#160; If you haven&amp;#39;t checked out any of these projects (admittedly I did not attempt to introduce them at all) I would encourage you do so.&amp;#160; One thing is for certain judging from the numbers above, these projects are viable, strong, and have a good following.&lt;/p&gt;  &lt;p&gt;What do you think of the figures above?&amp;#160; Is Ayende right?&amp;#160; What strikes you about the projects and their discussion groups?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=45003" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/jJmseRCNITM" height="1" width="1"/&gt;</description><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/03/16/open-source-maturity-model-revealed.aspx</feedburner:origLink></item><item><title>Debugging .NET Applications - Podcast Alert</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/gZKmSMfU2M0/debugging-net-application-podcast-alert.aspx</link><pubDate>Fri, 13 Mar 2009 19:38:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44952</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=44952</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/03/13/debugging-net-application-podcast-alert.aspx#comments</comments><description>&lt;p&gt;I have a penchant for taking &amp;quot;unsolvable&amp;quot; computer problems and getting to the bottom of them.&amp;nbsp; Often times this means I&amp;#39;m exploring the contents of a memory dump, that is, all of the data held in RAM of the process you&amp;#39;re inspecting.&amp;nbsp; When I got started in this area about 2+ years ago I found &lt;a href="http://blogs.msdn.com/tess/"&gt;Tess Ferrandez&amp;#39;s blog&lt;/a&gt; blog was a great resource.&amp;nbsp; In fact &lt;a href="http://www.timbarcz.com/blog/DebuggingNetApplicationsWithWinDBG.aspx"&gt;I&amp;#39;ve blogged about Tess and WinDBG before&lt;/a&gt;.&amp;nbsp; Her blog is one of my favorites when it comes to debugging and troubleshooting .NET applications (web or otherwise).&lt;/p&gt;  &lt;p&gt;Debugging and troubleshooting is a skill I think too many developers lack.&amp;nbsp; By debugging and troubleshooting I don&amp;#39;t mean stepping your way through code.&amp;nbsp; I mean, &amp;quot;Holy Crap our production app is failing and we don&amp;#39;t know why,&amp;quot; kind of debugging.&amp;nbsp; I think debugging is so valuable that I used to ask specific questions about it during interviews.&amp;nbsp; Too many times I could ask questions and see the developer try to answer, but often it was easy to see that if this was a real world scenario and not an interview question, they would have long ago thrown up their arms in defeat.&amp;nbsp; Computers are predictable, they don&amp;#39;t &amp;quot;decide&amp;quot; anything, they&amp;#39;re told what to do. If you understand that you&amp;#39;re a step ahead of the average developer when it comes to debugging and troubleshooting.&lt;/p&gt;  &lt;p&gt;Earlier this week &lt;a href="http://www.dotnetrocks.com"&gt;DotNetRocks&lt;/a&gt; interviewed &lt;a href="http://blogs.msdn.com/tess/"&gt;Tess Ferrandez&lt;/a&gt;, an escalation engineer with Microsoft.&amp;nbsp; She&amp;#39;s Tier 2 support. In other words, when you have a problem and call Microsoft you get Tier 1 support.&amp;nbsp; Then &amp;quot;when thinks get too sticky&amp;quot; she comes to the rescue.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;(I&amp;#39;d like to take a moment and have you consider the types of problems she gets.&amp;nbsp; The typical engineer will encounter many issues over their career.&amp;nbsp; I&amp;#39;m sure you&amp;#39;ve had them.&amp;nbsp; I&amp;#39;ve had them.&amp;nbsp; However, I typically will peruse articles, blog posts, and forum posts to find the answers I look for.&amp;nbsp; When faced with a problem, how many times have you ever resorted to calling Microsoft? Me? Zero. So imagine for a moment that you&amp;#39;ve not found an answer on any of the typical resources and have called Microsoft.&amp;nbsp; You&amp;#39;re working with their Tier 1 support but they can&amp;#39;t seem to help you.&amp;nbsp; It as it this point that you get a person like Tess.&amp;nbsp; She&amp;#39;s smart.&amp;nbsp; She know .NET like I know Mt. Dew).&lt;/p&gt;  &lt;p&gt;If you&amp;#39;re sitting at a desk download the podcast and listen now:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;MP3: &lt;a href="http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez.mp3"&gt;http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez.mp3&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;WMA: &lt;a href="http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez.wma" title="http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez.wma"&gt;http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez.wma&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;WMA Lo-Fi: &lt;a href="http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez_lo.wma" title="http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez_lo.wma"&gt;http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez_lo.wma&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;iPod: &lt;a href="http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez.m4b" title="http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez.m4b"&gt;http://perseus.franklins.net/dotnetrocks_0427_tess_ferrandez.m4b&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=44952" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/gZKmSMfU2M0" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/.NET+Framework/default.aspx">.NET Framework</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Debugging/default.aspx">Debugging</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/03/13/debugging-net-application-podcast-alert.aspx</feedburner:origLink></item><item><title>Real Life - Code Reuse</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/owMJtgRj8I4/real-life-code-reuse.aspx</link><pubDate>Mon, 09 Mar 2009 18:37:16 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44882</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>8</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=44882</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/03/09/real-life-code-reuse.aspx#comments</comments><description>&lt;p&gt;A few months ago I &lt;a href="http://devlicio.us/blogs/tim_barcz/archive/2009/01/05/real-life-single-responsibility-principle.aspx"&gt;blogged about how we&amp;#39;re using the single responsibility principle&lt;/a&gt; in our application at work.&amp;#160; I&amp;#39;m going to make an effort here to write more &amp;quot;Real Life&amp;quot; content.&amp;#160; Often when a developer read principles or ideas in books, there is disconnect between what he/she is reading and how an implementation would look in the real world.&amp;#160; The goal of these &amp;quot;Real Life&amp;quot; scenarios is to show areas where I feel I&amp;#39;ve reaped some benefit from following a specific pattern or practice.&amp;#160; This does not mean that my implementation is the only way or always &amp;quot;book correct&amp;quot;.&amp;#160; The goal is to act as a bridge (quite possibly a old rickety bridge) between the book knowledge and the real world.&lt;/p&gt;  &lt;p&gt;Moving along...&lt;/p&gt;  &lt;p&gt;One of the purported benefits of OOP has always been the abundant reuse of code.&amp;#160; However, in my experience many applications fail to realize any amount of reuse beyond copying and pasting between applications.&amp;#160; To really take advantage of code reuse you have to have small, concise pieces which you can rearrange in order to make a new behavior.&amp;#160; As a side note, and I want this be clear, many of the principles of good software development, ie. SOLID, go hand-in-hand.&amp;#160; You can&amp;#39;t do one without the other and the benefits of one cannot be fully realized without the implementation of the others.&amp;#160; You&amp;#39;ll notice that a few sentences ago I said &amp;quot;small, concise pieces&amp;quot;.&amp;#160; A light bulb may have gone off in your head thinking &amp;quot;Single Responsibility Principle&amp;quot;, and if it did, bonus points for you.&lt;/p&gt;  &lt;p&gt;The key to code reuse is to build your components in a very focused way.&amp;#160; By doing so, you can add functionality by combining different pieces of you application.&lt;/p&gt;  &lt;p&gt;Consider the following code used to authenticate a user into a site:&lt;/p&gt;  &lt;div&gt;   &lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;     &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; btnSubmit_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Username = Server.HtmlEncode(txtUsername.Text);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Password = Server.HtmlEncode(txtPassword.Text);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; nUserID;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (Username != &lt;span style="color:#006080;"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &amp;amp;&amp;amp; Password != &lt;span style="color:#006080;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (SqlConnection cnn = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnection(connectionString))&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt;         {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  11:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (SqlCommand cmd = cnn.CreateCommand())&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  12:&lt;/span&gt;             {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  13:&lt;/span&gt;                 cmd.CommandText = &lt;span style="color:#006080;"&gt;&amp;quot;usp_Login&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  14:&lt;/span&gt;                 cmd.Parameters.AddWithValue(&lt;span style="color:#006080;"&gt;&amp;quot;@Username&amp;quot;&lt;/span&gt;, Username);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  15:&lt;/span&gt;                 cmd.Parameters.AddWithValue(&lt;span style="color:#006080;"&gt;&amp;quot;@password&amp;quot;&lt;/span&gt;, password);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  16:&lt;/span&gt;                 &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  17:&lt;/span&gt;                 &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt;(SqlDataReader reader = cmd.ExecuteReader())&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  18:&lt;/span&gt;                 {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  19:&lt;/span&gt;                     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (reader.Read())&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  20:&lt;/span&gt;                     {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  21:&lt;/span&gt;                         nUserId = Convert.ToInt32(reader[0]);    &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  22:&lt;/span&gt;                     }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  23:&lt;/span&gt;                 }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  24:&lt;/span&gt;             }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  25:&lt;/span&gt;         }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  26:&lt;/span&gt;         &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  27:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (nUserID &amp;gt; 0)&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  28:&lt;/span&gt;         {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  29:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;// if the user has checked the box&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  30:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;// store his information so he doesn&amp;#39;t have to log in again&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  31:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cbRememberMe.Checked)&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  32:&lt;/span&gt;                 FormsAuthentication.SetAuthCookie(nUserID.ToString(), &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  33:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  34:&lt;/span&gt;                 FormsAuthentication.SetAuthCookie(nUserID.ToString(), &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  35:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  36:&lt;/span&gt;             BusinessLogicLayer.User objUser = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; User(nUserID);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  37:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  38:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;// store session variables for later reference;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  39:&lt;/span&gt;             Session[&lt;span style="color:#006080;"&gt;&amp;quot;UserID&amp;quot;&lt;/span&gt;] = nUserID;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  40:&lt;/span&gt;             Session[&lt;span style="color:#006080;"&gt;&amp;quot;Username&amp;quot;&lt;/span&gt;] = objUser.Username;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  41:&lt;/span&gt;             Session[&lt;span style="color:#006080;"&gt;&amp;quot;Password&amp;quot;&lt;/span&gt;] = objUser.Password;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  42:&lt;/span&gt;             Session[&lt;span style="color:#006080;"&gt;&amp;quot;AccessLevel&amp;quot;&lt;/span&gt;] = objUser.AccessLevel;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  43:&lt;/span&gt;             Session[&lt;span style="color:#006080;"&gt;&amp;quot;AccessLevelName&amp;quot;&lt;/span&gt;] = Enum.GetName(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Utilities.AccessLevel),objUser.AccessLevel);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  44:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  45:&lt;/span&gt;             Response.Redirect(&lt;span style="color:#006080;"&gt;&amp;quot;~/admin/admin.aspx&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  46:&lt;/span&gt;         }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  47:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  48:&lt;/span&gt;         {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  49:&lt;/span&gt;             View = Views.Failed;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  50:&lt;/span&gt;         }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  51:&lt;/span&gt;     }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  52:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;While the code above is functional, it does way too much.&amp;#160; In this button click event there are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Call to database explicitly &lt;/li&gt;

  &lt;li&gt;logic to set an authorization cookie &lt;/li&gt;

  &lt;li&gt;Some session variables being set &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagine for a moment that you now want to implement a new piece of functionality, user impersonation.&amp;#160; In order to accomplish this with the path of least resistance, which developers commonly take, would be to copy/paste all of the login logic to another UI event somewhere else in the site.&amp;#160; &lt;strong&gt;The issue copy/paste development is that any future change to the login logic has to be copied again or else the impersonation feature isn&amp;#39;t really impersonating a users experience.&lt;/strong&gt;&amp;#160; &lt;strong&gt;The insidious nature of copy/paste development is that while often it works, it creates a brittle application.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a recent application we were wanting to add user impersonation.&amp;#160; Below is an example of an implementation of user impersonation.&amp;#160; Adding the feature to the application was gleefully simple.&amp;#160; The ease in adding impersonation was due entirely to the proper granularity in our application components.&amp;#160; Seriously, this is all the code it took:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ActionResult ImpersonateUser(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; id)&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt;     var authService = Container.Resolve&amp;lt;AuthService&amp;gt;();&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;     var userRepository = Container.Resolve&amp;lt;UserRepository&amp;gt;();&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;     var userToImpersonate = userRepository.GetById(id);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (userToImpersonate != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;         authService.SignIn(userToImpersonate);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt;     }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  12:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; RedirectToAction(&lt;span style="color:#006080;"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;Home&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  13:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I did not know we were going to want user impersonation for this application when we started.&amp;#160; However because we developed the site with certain principles in mind, we were able to reuse pieces of code in ways not originally intended for added behavior.&amp;#160; As you can see from the code above, there are no &amp;quot;clever hacks&amp;quot; or tricks to get impersonation to work.&amp;#160; The beauty of the code above is that if we change the implementation of &amp;quot;SignIn(user)&amp;quot; all appropriate areas will follow the same rules since all areas use the same code.&lt;/p&gt;

&lt;p&gt;As I&amp;#39;m closing I want to challenge those of you who have read this far to stop yourself the next time you find yourself copying code from one location to another.&amp;#160; Is there an abstraction or component you&amp;#39;re overlooking?&amp;#160; Think about the long term and ask if you&amp;#39;re really making the wisest decision for the long term health of your application.&amp;#160; It will be through this introspection and honesty that you&amp;#39;ll find areas where you can write smaller component which will allow you to realize the oft spoken benefit in OOP of code reuse.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=44882" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/owMJtgRj8I4" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Principles/default.aspx">Principles</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/03/09/real-life-code-reuse.aspx</feedburner:origLink></item><item><title>Improving Software Process - A Letter to Upper Management</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/xhyyJ9qhls8/improving-software-process-a-letter-to-upper-management.aspx</link><pubDate>Thu, 05 Mar 2009 18:49:12 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44823</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>19</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=44823</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/03/05/improving-software-process-a-letter-to-upper-management.aspx#comments</comments><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;The following is an email I wrote to the upper management in our company when asked about things we can do to improve the process and what are the next steps of things we need to fix in our application.&amp;#160; It remains mostly unedited and contains my thoughts on what will make our company better when it comes to the software we&amp;#39;re writing.&amp;#160; It wasn&amp;#39;t written as a blog post.&amp;#160; It wasn&amp;#39;t until after I finished with it that I realized that it was decent content for a blog post.&amp;#160; You&amp;#39;ll find a very &amp;quot;XP-ish&amp;quot; theme throughout, and that isn&amp;#39;t necessarily an accident.&amp;#160; Hope you enjoy! Please leave feedback if something moves you.&lt;/p&gt;  &lt;h2&gt;Overview&lt;/h2&gt;  &lt;p&gt;The following contains my thoughts on software development at Super Awesome Company. While I can address the specifics of the project that I see need to be fixed and modified (the &amp;#8220;what&amp;#8221;), I am instead going to focus on how these items get fixed. I am choosing to do this because over time the new website will have bugs that need to be fixed, enhancements that need to be made, or new features requested. For the long term health of the project it does not matter so much &amp;#8220;what&amp;#8221; is implemented but rather &amp;#8220;how&amp;#8221;. For that reason I am avoiding specific project level tasks in this document and speaking at a higher level.&lt;/p&gt;  &lt;p&gt;Software has been being developed for over 30 years. While the internet is relatively young, software development by comparison is not. Super Awesome Company will benefit from a commitment to good software development practices. Further, it takes a great deal of commitment and discipline to reap the benefits these practices can bring. Many of my suggestions are based on these principles, which are principles I have committed to learning and adopting over the last several years.&lt;/p&gt;  &lt;p&gt;The overarching suggestion I would make is make quality the focus. In order to produce quality, we must slow down. In order to go fast you must go slowly. Sacrificing quality should never be an option. Consider a car manufacturer who needs to get 100 cars built in a single day. If they can only build 80 cars a day, is it better for them in the long run to get 100 cars out the door but have problems or 80 problem free cars? Building deficient cars carries more expense that just fixing the broken cars, such diminished brand reputation. If the goal is 100 cars per day, measures should be sought to increase production while keeping quality high.&lt;/p&gt;  &lt;p&gt;We don&amp;#39;t need to look too far to see where in a rush we&amp;#39;ve done something that we&amp;#39;ve had to revisit several more times because we were &amp;quot;going fast&amp;quot;. We&amp;#39;ve been rushed for nearly a year and I can&amp;#39;t say that we are any further along than we would have been had we approached the project more methodically. In some areas we may be further behind where we would have been since we &amp;quot;made sacrifices&amp;quot; to get things done, which have ultimately only put us further behind. Again, to go fast we must go &amp;quot;slow&amp;quot; (methodical). Put another way, quality breeds speed.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Any process, principle, practice we choose should have quality at its heart. Regardless of what process, principles, practices we adopt they will only be successful if we are disciplined enough to follow them. &lt;/b&gt;&lt;/p&gt;  &lt;h2&gt;Planning&lt;/h2&gt;  &lt;h3&gt;Requirements &lt;/h3&gt;  &lt;p&gt;Requirements need to be clear and understood by all parties. Before developers set out to coding we need to have a clear understanding of what the problem is. The developer is not able to provide a solution until the problem is fully known and understood. Often the perceived solution to a problem is not the best solution. Failure to fully understand the problem/scenario results in rework.&lt;/p&gt;  &lt;h3&gt;Releases&lt;/h3&gt;  &lt;p&gt;We need to have planned releases. The timeframe can be discussed and agreed upon by the team. In order to have successful releases we need to plan each release. Each release should be broken down into smaller time frames, iterations. During the iteration the work should be stable for each developer. In other words, they know what they&amp;#8217;re going to work on and accomplish (see requirements above) for any given time period.&lt;/p&gt;  &lt;h3&gt;Metrics&lt;/h3&gt;  &lt;p&gt;We need to be measuring metrics for the purposes of planning. If we get 10 units of work done each week on average and we have 20 units of work to do, we can easily figure out what is left to do. Without any metrics gathering we can&amp;#8217;t do any planning and we&amp;#8217;re really flying blind. This will also help with project post mortems. For example, the &amp;#8220;web order manager&amp;#8221; project was originally estimated to take a week worth of development effort. Three months later, it is still not finished. This is a combination of putting someone with limited knowledge of the business estimating the project, an overly aggressive developer estimate, and having no metric to pull from on how long something should take.&lt;/p&gt;  &lt;h3&gt;Flexibility&lt;/h3&gt;  &lt;p&gt;We need to be disciplined in the process of building software, but also realize when the process needs tweaking that we should respond and not be afraid to tweak the process to meet the needs of our team&lt;/p&gt;  &lt;h2&gt;Design&lt;/h2&gt;  &lt;h3&gt;Simplicity&lt;/h3&gt;  &lt;p&gt;We should strive for simplicity in our designs. &amp;#8220;Clever hacks&amp;#8221; are often not healthy for the life time of the project. Simple designs are easier to understand and improve upon. Simple designs also allow other developers ease in working on code. This is much harder to do in practice but it always pays off in the long run.&lt;/p&gt;  &lt;p&gt;Design aspects dovetail with testing (later in this document). Typically complex designs prove to be hard to test. When we write code based on simpler designs we&amp;#8217;ll find that our code is easier to test. We want both, simple designs and easy-to-test code.&lt;/p&gt;  &lt;h2&gt;Coding&lt;/h2&gt;  &lt;h3&gt;Standards&lt;/h3&gt;  &lt;p&gt;We should implement a standard for code development. Right now you can find three different styles/methods of coding in the code base. This makes it hard for developers to work on code they did not author. Projects I work on outside of work require all new code meet the standard, otherwise it is rejected until it meets this standard. As a consumer of these projects I&amp;#8217;m always grateful when I can move through any of the project pieces and the code always looks the same.&lt;/p&gt;  &lt;h3&gt;Testing&lt;/h3&gt;  &lt;p&gt;Given the environment and complexity of the code, we need to require the developers to be able to test their code in an automated fashion. Visual verification is orders of magnitude slower than automated testing. Once an automated test is written, it runs every time. By having a large collection of tests we can makes changes to certain parts of the application and use existing tests as a safety net to verify nothing else has broken. We currently have over 1,150 tests (about 30% of code has tests) that run whenever someone commits code into source control. Those tests run in about 20 seconds. Imagine how long it would take a user to test each of those cases visually every time a piece of code changes.&lt;/p&gt;  &lt;p&gt;Two weeks ago I sat in a meeting adding functionality to shipping and enhancing rules around shipping hazardous items to Canada while people were finding issues because of a solid base of tests. Before the meeting was over both issues discovered were fixed and tests were added for these specific issues so we would be guarded against this happening again.&lt;/p&gt;  &lt;h3&gt;Unit Tests&lt;/h3&gt;  &lt;p&gt;All code must have unit tests that can be run in an automated fashion. If the code cannot be unit tested (tested in isolation from other components) it should be restructured in such a way that it can be tested. Very few pieces of code are truly not testable. As such we should have very few areas in our code base which are not tested.&lt;/p&gt;  &lt;h3&gt;Proving Bug Fixes Through Tests&lt;/h3&gt;  &lt;p&gt;When bug is found a test should be written before any attempt to fix the bug. This test proves to the developer the bug exists but secondly gives the developer a marker to know when the bug is fixed. As a benefit, this new test acts as a guard against this particular bug ever happening again. This test, when first written, should fail because the developer has not fixed the bug yet. The developer should then work to make the test pass, and by extension fixing the bug. The cost of adding the test is very small when compared against having the test guard against this condition ever happening again. &lt;/p&gt;  &lt;h3&gt;Code Coverage&lt;/h3&gt;  &lt;p&gt;We should implement a standard for new code coverage, code that is tested by an automated test. I would recommend somewhere in the 80%-90% range for code coverage. In order to write tests the developers will be forced to think about their code a bit more thoroughly.&lt;/p&gt;  &lt;h3&gt;Pair Programming&lt;/h3&gt;  &lt;p&gt;We should adopt pair programming as a method to both increase shared knowledge but also as a means to quality. Pair programming is two developers sitting at one computer for a period of time while code is written. From the outside it may seem impractical to devote two developers to a single computer, thinking it is inefficient. Industry studies however show that code written in a pair has a four-fold benefit:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;15% less code&amp;#8211; Studies showed that less code is written in order to implement the same functionality. Less code means less to maintain and understand. Less code is also typically simpler. &lt;/li&gt;    &lt;li&gt;Less bugs &amp;#8211; Developers, when working in pairs, can catch each other&amp;#8217;s bugs before they ever make it to production. We therefore save time that it would take to fix the bugs that would otherwise go undiscovered. &lt;/li&gt;    &lt;li&gt;Shared domain knowledge &amp;#8211; When &amp;#8220;pairing&amp;#8221;, each developer is training the other and sharing knowledge and rules around the business. This avoids silos and situations where only one person knows the code. &lt;/li&gt;    &lt;li&gt;Increased Skill &amp;#8211; When &amp;#8220;pairing&amp;#8221;, design, coding, and testing techniques are transferred between developers. This is often why many development shops pair their senior developers with junior developers; to raise the skill level of the junior developer. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Collective Code Ownership&lt;/h3&gt;  &lt;p&gt;No one person should be a silo/bottleneck for any area of the code. Any person should be free to make suggestions, fix bugs, or refactor any part of the code. Pair programming (see above) is one tool which seeks to address this.&lt;/p&gt;  &lt;h2&gt;Conclusion&lt;/h2&gt;  &lt;p&gt;While the above recommendations may seem like a lot, the above items all really go hand-in-hand. Consider:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Collective Code Ownership&lt;/b&gt; is had through &lt;b&gt;Pair Programming&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Standards&lt;/b&gt; are enforced by developers when &lt;b&gt;Pair Programming&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;Writing &lt;b&gt;Unit Tests&lt;/b&gt; typically leads to &lt;b&gt;Simple Designs&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;A commitment to &lt;b&gt;Code Coverage&lt;/b&gt; leads to more &lt;b&gt;Unit Tests&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;Gathering &lt;b&gt;Metrics&lt;/b&gt; leads to better estimates and &lt;b&gt;Release &lt;/b&gt;planning &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Adopting the above will move us in a positive direction and ensure that all projects coming from our department will be of ever heightening quality. Once the quality bar is set, then we will begin to see the pace pick up; Remember, quality is a prerequisite to speed.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=44823" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/xhyyJ9qhls8" height="1" width="1"/&gt;</description><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/03/05/improving-software-process-a-letter-to-upper-management.aspx</feedburner:origLink></item><item><title>Default Values and Smarter Property Assessors</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/h-9ttoObTns/default-values-and-smarter-property-assessors.aspx</link><pubDate>Mon, 02 Mar 2009 03:18:14 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44749</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>7</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=44749</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/03/01/default-values-and-smarter-property-assessors.aspx#comments</comments><description>&lt;p&gt;In your applications there may be times when you want to give the user the ability to override a setting or configuration value.&amp;#160; Often times you want to provide sensible defaults so that every single configuration option does not have to be specified, only those you which to override.&amp;#160; I want to show a very simple way to make your applications a bit smarter when creating classes with overridable default values.&lt;/p&gt;  &lt;h3&gt;Example 1:&lt;/h3&gt;  &lt;div&gt;   &lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;     &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; DemoObejct&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; DEFAULT_MESSAGE = &lt;span style="color:#006080;"&gt;&amp;quot;Thank you for your order&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;     &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; message = DEFAULT_MESSAGE;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;     &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Message&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;         get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; message; }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt;         set { message = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;; }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  12:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h3&gt;Example 2:&lt;/h3&gt;

&lt;div&gt;
  &lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; DemoObejct&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; DEFAULT_MESSAGE = &lt;span style="color:#006080;"&gt;&amp;quot;Thank you for your order&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;     &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; message;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;     &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Message&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;         get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; message ?? DEFAULT_MESSAGE; }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt;         set { message = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;; }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  12:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;So what&amp;#39;s the difference?&amp;#160; The difference IS subtle but I consider the following code snippet:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; var obj = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DemoObject();&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt; Console.WriteLine(obj.Message);&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt; obj.Message = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt; Console.WriteLine(obj.Message);&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Setting the Message property to null in line 5 results in different behavior between the two examples.&amp;#160; I find the second example to be preferable, setting the property to null invokes the default message again.&amp;#160; It&amp;#39;s a very simple thing you can do to provide a more robust object&lt;/p&gt;

&lt;p&gt;Here are two more examples where I use this strategy often:&lt;/p&gt;

&lt;h3&gt;Integers and Default Values:&lt;/h3&gt;

&lt;div&gt;
  &lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; DemoObject&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;? attemptThreshold;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; DEFAULT_ATTEMPTTHRESHOLD = 3;        &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;         &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; AttemptThreshold&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt;     {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt;         get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; attemptThreshold.HasValue ? attemptThreshold.Value : DEFAULT_ATTEMPTTHRESHOLD; }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;         set { attemptThreshold = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;; }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt;     }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  11:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h3&gt;Logging Component:&lt;/h3&gt;

&lt;div&gt;
  &lt;div style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; DemoObject&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; ILogger logger;&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ILogger Logger&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt;         get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; logger ?? NullLogger.Instance; }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt;         set { logger = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;; }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;     }&lt;/pre&gt;

    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;border-top-style:none;line-height:12pt;padding-top:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;border-bottom-style:none;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The above logging example is where this type of strategy really shines.&amp;#160; It prevents NullReferenceExceptions in your code if by chance your logger gets a null value at some point, again providing for a more robust object and application.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=44749" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/h-9ttoObTns" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Tips+And+Tricks/default.aspx">Tips And Tricks</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/03/01/default-values-and-smarter-property-assessors.aspx</feedburner:origLink></item><item><title>Look What I Found</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/dwd0JJP1hBE/look-what-i-found.aspx</link><pubDate>Tue, 10 Feb 2009 18:00:52 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44090</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=44090</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/02/10/look-what-i-found.aspx#comments</comments><description>&lt;p&gt;Digging through the &lt;a href="http://www.castleproject.org/"&gt;Castle&lt;/a&gt; source code look what I found in the &amp;quot;HowToBuild&amp;quot; file (note the last line):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Possible problem with 3.5      &lt;br /&gt;=========================       &lt;br /&gt;if you get the following error:       &lt;br /&gt;&amp;quot;The SDK for the &amp;#39;net-3.5&amp;#39; framework is not available or not configured.&amp;quot;       &lt;br /&gt;then you probably need to fix the sdkInstallRoot in your nant.exe.config file to point to the correct location in the registry       &lt;br /&gt;See the following article for more info:       &lt;br /&gt;&lt;strong&gt;http://www.timbarcz.com/blog/NantSetupForVisualStudio2008AndNet35.aspx&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Looking through the file&amp;#39;s history I can see that &lt;a href="http://www.kenegozi.com/blog/"&gt;Ken Egozi&lt;/a&gt; is a pretty smart man. *wink* *wink*&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=44090" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/dwd0JJP1hBE" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Castle+Project/default.aspx">Castle Project</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Open+Source+Software/default.aspx">Open Source Software</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/02/10/look-what-i-found.aspx</feedburner:origLink></item><item><title>Testing - Mandated By God!</title><link>http://feedproxy.google.com/~r/TimBarcz/~3/Mrq4lTBc8IE/testing-mandated-by-god.aspx</link><pubDate>Tue, 10 Feb 2009 14:21:31 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:44082</guid><dc:creator>Tim Barcz</dc:creator><slash:comments>6</slash:comments><wfw:commentRss>http://devlicio.us/blogs/tim_barcz/rsscomments.aspx?PostID=44082</wfw:commentRss><comments>http://devlicio.us/blogs/tim_barcz/archive/2009/02/10/testing-mandated-by-god.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.biblegateway.com/passage/?search=I%20Thessalonians%205:21"&gt;1 Thessalonians 5:21&lt;/a&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&amp;quot;Test everything. Hold on to the good.&amp;quot; (NIV)&lt;/li&gt;    &lt;li&gt;&amp;quot;Prove all things; hold fast that which is good.&amp;quot; (King James Version)&lt;/li&gt; &lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=44082" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/TimBarcz/~4/Mrq4lTBc8IE" height="1" width="1"/&gt;</description><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Testing/default.aspx">Testing</category><category domain="http://devlicio.us/blogs/tim_barcz/archive/tags/Humor/default.aspx">Humor</category><feedburner:origLink>http://devlicio.us/blogs/tim_barcz/archive/2009/02/10/testing-mandated-by-god.aspx</feedburner:origLink></item></channel></rss>
