<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" 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/"><channel><title>Jak Charlton - Insane World : Agile</title><link>http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx</link><description>Tags: Agile</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Trust, Honesty, Openness, Cooperation and Friction-free Tooling</title><link>http://devlicio.us/blogs/casey/archive/2011/05/03/trust-honesty-openness-cooperation-and-friction-free-tooling.aspx</link><pubDate>Tue, 03 May 2011 22:59:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:67188</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=67188</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=67188</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2011/05/03/trust-honesty-openness-cooperation-and-friction-free-tooling.aspx#comments</comments><description>&lt;p&gt;There is an inherent danger in using electronic tools to manage a process like software development, and one that almost always comes true - the tool defines your process, it doesn&amp;#39;t enable it.&lt;/p&gt;
&lt;p&gt;When people encounter limitations in the software tool, they begin to accept that these are limitations of the process and these become ingrained in your methodology. If the tool doesn&amp;#39;t support the &amp;quot;thing you want to do&amp;quot; then it is far easier to change the &amp;quot;thing&amp;quot; rather than rewrite or change the software.&lt;/p&gt;
&lt;p&gt;Were any of the electronic tools to have got the process &amp;quot;right&amp;quot; this might not be such a bad thing, but it would be reasonable to assume that in a field as adaptive and evolutionary as software development there is no such thing as the &amp;quot;right&amp;quot; process for an individual team, let alone for such a widely disparate ecosystem as development.&lt;/p&gt;
&lt;p&gt;And this conflict between our tools and our actual practices and processes is what we refer to as &amp;quot;friction&amp;quot;, and as physics defines it;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Friction is the &amp;quot;evil&amp;quot; of all motion. No matter which direction something moves in, friction pulls it the other way. Move something left, friction pulls right. Move something up, friction pulls down. It appears as if nature has given us friction to stop us from moving anything.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;We aim for &amp;quot;friction-free&amp;quot; tools to allow us to better get on with moving things, specifically developing software, which is a constantly moving and adaptive process.&lt;/p&gt;
&lt;p&gt;Some tools aim to allow endless configuration or programmability, in their objective of being a universal solution. These tools tend to actually make the problem worse, by either leaving you bogged down in configuration or customisation, or leaving the tool so generic that it solves no problem at all.&lt;/p&gt;
&lt;p&gt;Of course, some tools are better than others. Lightweight tools are obviously going to create less friction as they have less moving parts, and less touch points with your actual process.&amp;nbsp;&amp;nbsp;But these are the ones that some see as &amp;quot;lacking features&amp;quot;, or as being &amp;quot;too simplistic&amp;quot; - but it is these things specifically that enable the process of development to continue.&lt;/p&gt;
&lt;p&gt;And ultimately, these tools expose a greater problem - there is usually a disjoint between project management and the development teams here. A lack of trust and visibility leads managers to seek to control or monitor the process more tightly, and these tools promise to allow that to happen. Surely if we can tie everything into a database or a spreadsheet or something similar, we can then see exactly what is happening, who is doing what, when things will be done, and how long they will take?&lt;/p&gt;
&lt;p&gt;But it is not the tool that enables this to happen - it is serving here merely to try and enforce control upon people - which as any good manager knows, enforcement is a far blunter instrument than cooperation.&lt;/p&gt;
&lt;p&gt;What enables proper management of the software development process is trust, honesty, openness and cooperation. Tools should reflect and enable those objectives, rather than try to enforce them. And most importantly, they should stay out of the way of the development teams to allow them to get on with their real job - developing software.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=67188" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Practices+and+Principles/default.aspx">Practices and Principles</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Rants/default.aspx">Rants</category></item><item><title>Agile is Performance, Feedback, Revision</title><link>http://devlicio.us/blogs/casey/archive/2010/04/15/agile-is-performance-feedback-revision.aspx</link><pubDate>Thu, 15 Apr 2010 02:45:08 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:57265</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=57265</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=57265</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2010/04/15/agile-is-performance-feedback-revision.aspx#comments</comments><description>&lt;p&gt;I came across a great video link yesterday, entitled “&lt;a href="http://blog.newhumanist.org.uk/2010/03/see-baba-brinkmans-rap-guide-to.html" target="_blank"&gt;Performance, Feedback, Revision&lt;/a&gt;”. It’s a Canadian rapper named Baba Brinkman covering the theory of evolution and the work of Charles Darwin, and he equates evolution with how he writes his lyrics, Performance, Feedback, Revision.&lt;/p&gt;  &lt;p&gt;As I listened to it, it struck me that this is Agile … we develop, we run retrospectives, and we revise what we have.&lt;/p&gt;  &lt;p&gt;Evolution may be more like waterfall, and take millions of years to evolve something as fundamentally pointless as the &lt;a href="http://www.talkorigins.org/faqs/vestiges/appendix.html" target="_blank"&gt;appendix&lt;/a&gt;, and in Agile we may look to have Performance, Feedback and Revision inside a week or two.&lt;/p&gt;  &lt;p&gt;I can’t quite believe I just showed this video to a client to explain Agile, but it seemed to get the idea across pretty well. I’m considering using it more often, but I promise to draw the line at learning to rap.&lt;/p&gt;  &lt;p&gt;But from now on, in big letters across the top of my white boards will go the words:&lt;/p&gt;  &lt;h3 align="center"&gt;Performance, Feedback, Revision&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=57265" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Rants/default.aspx">Rants</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>Ship it, or Ship Out</title><link>http://devlicio.us/blogs/casey/archive/2009/09/25/ship-it-or-ship-out.aspx</link><pubDate>Fri, 25 Sep 2009 08:38:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:51716</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>27</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=51716</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=51716</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2009/09/25/ship-it-or-ship-out.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.joelonsoftware.com/"&gt;Joel&lt;/a&gt;, in his inimitable way, &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html"&gt;posted the flame bait of all flame bait posts yesterday&lt;/a&gt;, explaining the role of the Duct Tape Programmer.&lt;/p&gt;
&lt;p&gt;To my surprise, the Twitterverse started to reverberate with commentary, but weirdly, almost all of it was very negative about the post, many claiming that Joel was just creating straw men and knocking them down, or was characterising developers who care about quality as being poor developers.&lt;/p&gt;
&lt;p&gt;I was surprised, because I read the article totally the other way around - and had said so earlier in the day to someone on Twitter, saying I largely agreed with it. It seems that there were two ways of reading the article, and mine differed substantially to most people I follow on Twitter.&lt;/p&gt;
&lt;p&gt;I was quite pleased to see Michael Neel post last night in a &lt;a href="http://devlicio.us/blogs/vinull/archive/2009/09/24/being-a-duct-tape-programmer.aspx"&gt;semi-defence of Joel&amp;#39;s standpoint&lt;/a&gt;, and I thought the 140 char limit of Twitter wasn&amp;#39;t enough for me to post my opinions.&lt;/p&gt;
&lt;h3&gt;Background&lt;/h3&gt;
&lt;p&gt;Joel has a bit of a record on this, he isn&amp;#39;t best liked by a large proportion of the developer community who see their focus and remit as producing high quality, well tested and highly maintainable software. His &lt;a href="http://blog.stackoverflow.com/2009/01/podcast-38/"&gt;original tirades in a podcast&lt;/a&gt; about his deep distrust of Test Driven Development and of Unit Testing in &lt;a href="http://blog.objectmentor.com/articles/2009/01/31/quality-doesnt-matter-that-much-jeff-and-joel"&gt;general brought uproar&lt;/a&gt;. And on that matter he was so far off the mark, it was understandable why he had riled so many people - he really just didn&amp;#39;t understand or &amp;quot;get&amp;quot; TDD or testing in general.&lt;/p&gt;
&lt;p&gt;But, what he had done, in conjunction with &lt;a href="http://www.codinghorror.com/blog/"&gt;Jeff Atwood&lt;/a&gt;, was to deliver a website, &lt;a href="http://stackoverflow.com/"&gt;stackoverflow.com&lt;/a&gt;, that was proving hugely successful, and was being used extensively by all those same developers who railed against his podcasts and blogs.&lt;/p&gt;
&lt;p&gt;That website, as Joel and Jeff explained, was not done with TDD, was not well tested (via Unit Tests), was badly hacked together in places, and used &amp;quot;old&amp;quot; technologies like TSQL over &amp;quot;modern&amp;quot; solutions like ORMs&lt;/p&gt;
&lt;p&gt;Whether Joel &amp;quot;got&amp;quot; TDD wasn&amp;#39;t important, what he and Jeff had done was to ship a product, get it to market, and build upon that release to make stackoverflow the massive success it is today. It&amp;#39;s so successful, that soon after stackoverflow was released, they used the same code and model to release other Q&amp;amp;A sites, and they continue to do so.&lt;/p&gt;
&lt;h3&gt;The Duct Tape Programmer&lt;/h3&gt;
&lt;p&gt;So with all of that in mind, it was sort of obviously flame bait for Joel to make a post that basically boiled down to &amp;quot;shipping it way more important than fancy patterns and great tools&amp;quot; - he certainly has a way of putting such a simple message that can antagonise the meekest of individuals (and some not so meek). &lt;/p&gt;
&lt;p&gt;It was a terrible choice of label, but I guess &amp;quot;Pragmatic Programmer&amp;quot; had already been taken.&lt;/p&gt;
&lt;h3&gt;Time, Quality, Functionality&lt;/h3&gt;
&lt;p&gt;I read the article slight differently - I read it as an urge to maintain your highest priority as shipping the product your business wants you to ship.&lt;/p&gt;
&lt;p&gt;There are three factors involved in a project (if you exclude Resourcing, which falls under Brooks Law):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Time&lt;/li&gt;
&lt;li&gt;Quality&lt;/li&gt;
&lt;li&gt;Functionality (or Scope)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you try and maintain all three factors as fixed, your project is doomed to fail. Something will, unless you are really lucky, break. And then one of those factors will suffer, and it will be luck as to which it is. At best you can fix two of those factors, and then the third has to be allowed to slip when the unexpected happens (as it always does).&lt;/p&gt;
&lt;p&gt;But, the important part here, is that which of those factors is fixed, and which is allowed to slip is NOT a developer decision - it is a business decision.&lt;/p&gt;
&lt;p&gt;Much of the outrage about Joel&amp;#39;s article stated that he isn&amp;#39;t a developer - and they are correct - he is a business owner, and prior to that a project manager. His focus is therefore on shipping his product, and inevitably from that perspective, the instinct is to fix Time and Functionality (ship as soon as possible, with as much functionality as possible) and to let Quality suffer to achieve that objective.&lt;/p&gt;
&lt;p&gt;This is a TOTALLY VALID business decision - it is just one that developers don&amp;#39;t like, it offends their sense of code quality and high standards.&lt;/p&gt;
&lt;h3&gt;Why Do Developers Care So Much About Quality?&lt;/h3&gt;
&lt;p&gt;I&amp;#39;ll start with the cynical view: development is only fun while you are trying new things, trying to perfect a tricky algorithm, or make some great new OSS component do some magic. By nature, the developers who care deeply about quality are also perfectionists, they like to make sure they have done a good job, and have written the best code they can.&lt;/p&gt;
&lt;p&gt;Go on, admit it, if developers just did routine coding all day long, our jobs would be boring. We like new toys, new language features, we like to play.&lt;/p&gt;
&lt;p&gt;And we know that better code will be easier to maintain - and developers HATE bug fixing duty, so we want to ensure we don&amp;#39;t have to do much of it.&lt;/p&gt;
&lt;p&gt;To a developer, the most important factor in any project is Quality, followed by Time (because we know our bosses will be mad if we miss our deadlines), but we are happy to slip Functionality because it matters little to us if a new feature isn&amp;#39;t included in the release.&lt;/p&gt;
&lt;h3&gt;Fundamentally We Are Not Aligned&lt;/h3&gt;
&lt;p&gt;Developers and business owners are not aligned in their goals - we prioritise the three factors very differently, and for different reasons.&lt;/p&gt;
&lt;p&gt;Only two things can happen here, your developers need to align with their business objectives, or the business needs to align with the developers - or they can both compromise.&lt;/p&gt;
&lt;p&gt;Agile is all about the compromise, making both sides aware of the issues involved, and then coming to an agreement, but fundamentally - it is STILL A BUSINESS DECISION.&lt;/p&gt;
&lt;p&gt;While it is the responsibility of a professional developer to explain all the problems they see with low quality code, and to make their boss aware of all the potential future issues this may cause, it is also their professional responsibility to go with the decision their boss makes.&lt;/p&gt;
&lt;p&gt;They have one other option - resign and go somewhere that is more closely aligned with their values.&lt;/p&gt;
&lt;h3&gt;Ship It or Ship Out&lt;/h3&gt;
&lt;p&gt;Whatever your opinions of Joel and Jeff&amp;#39;s understandings of TDD, Unit testing, maintainable code or just code in general (and I&amp;#39;m sure yours aren&amp;#39;t too far from mine), you have to admit they delivered a product to market (many in fact), and have turned it into a huge success. They may have to pay for that speed to market later, but that was a business decision they were willing to take.&lt;/p&gt;
&lt;p&gt;Never underestimate the value to a business of being fast to market - there is a risk the product will be so bugged it will backfire - but there is a chance they could steal the march on their competitors, and gain critical traction. Business is all about assessing risk, that is what a business owner has to do, and if they do it right their business flourishes.&lt;/p&gt;
&lt;p&gt;If your boss wants a product shipped by a particular date, and that is their highest priority, you have a responsibility to ship it. If they won&amp;#39;t sacrifice functionality to achieve that goal, then code quality will have to suffer - in that case do the best you can do with the restraints you are under. And if all that fails, quit, go somewhere that appreciates your values and dedication to your art - you do not have a right to hold your employer to ransom.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So, Ship It or Ship Out.&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=51716" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/TDD/default.aspx">TDD</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Rants/default.aspx">Rants</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Twitter/default.aspx">Twitter</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Testing/default.aspx">Testing</category></item><item><title>Don't Tell Me "How", Tell me "What"</title><link>http://devlicio.us/blogs/casey/archive/2008/09/17/don-t-tell-me-quot-how-quot-tell-me-quot-what-quot.aspx</link><pubDate>Wed, 17 Sep 2008 11:55:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:42330</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=42330</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=42330</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/09/17/don-t-tell-me-quot-how-quot-tell-me-quot-what-quot.aspx#comments</comments><description>&lt;p&gt;During a discussion with our project manager earlier today, I used the phrase &amp;quot;Don&amp;#39;t tell me how you want it to work, tell me what you want it to do&amp;quot;&lt;/p&gt;
&lt;p&gt;We were discussing &lt;a class="" href="http://en.wikipedia.org/wiki/User_story"&gt;user stories&lt;/a&gt;, and I was trying to get across what I wanted to see on a story card, and what I didn&amp;#39;t want to see. He had put a story card on the wall that read:&lt;/p&gt;
&lt;p&gt;On the login screen:&lt;br /&gt;Should be a username box&lt;br /&gt;Should be a password box&lt;br /&gt;Should be a change password link&lt;br /&gt;Should be a remember me link&lt;br /&gt;Should be a register link&lt;/p&gt;
&lt;p&gt;As user stories go, this pretty much sucks as badly as it could. He was trying to tell me how to write a login page, as he saw it, but he wasn&amp;#39;t describing what functionality he wanted the accounts system to have.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Don&amp;#39;t Tell Me &amp;quot;How&amp;quot;, Tell me &amp;quot;What&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My user stories for a similar scenario would be more like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;&lt;em&gt;As a registered user I want to be able to use my existing account details to sign in to the site to allow me to access restricted content&lt;/em&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;em&gt;As a registered user I want the site to offer to remember me when I sign in so I don&amp;#39;t have to enter my details every visit&lt;/em&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;em&gt;As a registered user I want to be able to get a password reminder so that I can login even when I have forgotten my password&lt;/em&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;em&gt;As a registered user I want to be able to change my password so that my account is more secure&lt;/em&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;em&gt;As a new user I want to be able to register on the site and receive a username and password&lt;/em&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;None of these say how the user achieves the objectives, but they do encapsulate what functionality is actually required. The first card would have had a developer acting as a parrot and likely producing something that missed the goals widely. The second version allows the developer to see how all these functions will interact, and to make a page that best reflects the requirements ... it also happens that the second set of cards neatly becomes a directly applicable&amp;nbsp;UAT script.&lt;/p&gt;
&lt;p&gt;Now we can easily adapt the functionality to new requirements, for example these stories encourage a separation of the view from the actual functionality, so it is more likely we can put a login box on every page, or provide a register by email option instead of filling out a form.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What Format Should Stories Be In?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Traditionally I have tended to go for a simple format:&lt;/p&gt;
&lt;p&gt;As a &lt;em&gt;[insert role or type of user here]&lt;br /&gt;&lt;/em&gt;I want to &lt;em&gt;[insert required fucntionality here]&lt;br /&gt;&lt;/em&gt;So that&lt;em&gt; [insert business benefit, or desired outcome here]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There is a &lt;a class="" href="http://dannorth.net/whats-in-a-story"&gt;pretty good write up of this on Dan North&amp;#39;s site&lt;/a&gt;, so to save me repeating it, check his page out, he also steps into BDD style stories too, and how they reflect various scenarios.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=42330" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Practices+and+Principles/default.aspx">Practices and Principles</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category></item><item><title>Domain Driven Design Quickly - InfoQ</title><link>http://devlicio.us/blogs/casey/archive/2008/09/01/domain-driven-design-quickly-infoq.aspx</link><pubDate>Mon, 01 Sep 2008 11:52:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:42121</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=42121</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=42121</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/09/01/domain-driven-design-quickly-infoq.aspx#comments</comments><description>&lt;p&gt;A little earlier today I found myself explaining Aggregate Roots and Anemic Domain Models to a couple of developers here, and I wished I had my copy of Domain Driven Design to hand to show them what I was explaining ... then I remembered that InfoQ published an *excellent* online book called &amp;quot;&lt;a class="" href="http://www.infoq.com/minibooks/domain-driven-design-quickly"&gt;Domain Driven Design Quickly&lt;/a&gt;&amp;quot; - free to download, or you can buy the printed version. This book is a perfect introduction to DDD, and as it is free, you cannot really beat if for value for money!&lt;/p&gt;
&lt;p&gt;From the introduction:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The most complicated aspect of large software projects is not the implementation, it is the real world domain that the software serves. Domain Driven Design is a vision and approach for dealing with highly complex domains that is based on making the domain itself the main focus of the project, and maintaining a software model that reflects a deep understanding of the domain. The vision was brought to the world by Eric Evans in his book &amp;quot;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0321125215/domainlanguag-20"&gt;Domain Driven Design&lt;/a&gt;&amp;quot;. Eric&amp;#39;s work was based on 20 years of widely accepted best practices in the object community, as well as Eric&amp;#39;s own insights.&amp;nbsp; Domain Driven Design &lt;span style="FONT-STYLE:italic;"&gt;Quickly &lt;/span&gt;is a short, quick-readable summary and introduction to the fundamentals of DDD. A special interview with Eric Evans on the state of Domain Driven Design is also included.&lt;/p&gt;&lt;/blockquote&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=42121" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/DDD/default.aspx">DDD</category></item><item><title>NDepend ... the Shortest Review Ever</title><link>http://devlicio.us/blogs/casey/archive/2008/08/19/ndepend-the-shortest-review-ever.aspx</link><pubDate>Tue, 19 Aug 2008 08:14:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:41903</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=41903</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=41903</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/08/19/ndepend-the-shortest-review-ever.aspx#comments</comments><description>&lt;p&gt;A long while ago I got a licence for &lt;a class="" href="http://www.ndepend.com/"&gt;NDepend&lt;/a&gt; ... I had used it previously but only on the trial version, where it had proved very useful in giving me a some pretty graphs that made sense to managment when my words did not.&lt;/p&gt;
&lt;p&gt;I haven&amp;#39;t actually got around to using it until this morning, when I thought I would run it over our current project to see where we were at. There isn&amp;#39;t a hell of a lot of code in the project, so I wasn&amp;#39;t expecting too many surprises - and largely I didn&amp;#39;t receive many.&lt;/p&gt;
&lt;p&gt;I was pleased to see our assembly dependencies were the right way around, and very pleased to see they were very near the centre line on the &amp;quot;Abstractness vs Instability&amp;quot; chart.&lt;/p&gt;
&lt;p&gt;The only very mild surprise was to see this flagged up in multiple CQL checks:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;RegisterforUpdates(String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Obviously there is something wrong here ... and a quick word with the developer who wrote this established that he didn&amp;#39;t know about the Binding Helpers in ASP.NET MVC so had passed every form field back into the controller via the parameter list. A quick hyperlink to him of &lt;a class="" href="http://blog.wekeroad.com/2007/12/05/aspnet-mvc-preview-using-the-mvc-ui-helpers/"&gt;Rob Conery&amp;#39;s excellent tutorials&lt;/a&gt; on ASP.NET MVC and we have a much nicer method on the controller.&lt;/p&gt;
&lt;p&gt;One small win for &lt;a class="" href="http://www.ndepend.com/"&gt;NDepend&lt;/a&gt; ... I look forward to many more as time goes on!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=41903" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/casey/archive/tags/NDepend/default.aspx">NDepend</category></item><item><title>Software Development is a Creative Skill, Building Houses is a Technical One</title><link>http://devlicio.us/blogs/casey/archive/2008/08/18/software-development-is-a-creative-skill-building-houses-is-a-technical-one.aspx</link><pubDate>Mon, 18 Aug 2008 06:26:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:41878</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=41878</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=41878</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/08/18/software-development-is-a-creative-skill-building-houses-is-a-technical-one.aspx#comments</comments><description>&lt;p&gt;&lt;a class="" href="http://bradwilson.typepad.com/"&gt;Brad Wilson&lt;/a&gt; mentioned on the &lt;a class="" href="http://groups.yahoo.com/group/testdrivendevelopment"&gt;TDD mailing list&lt;/a&gt; that the waste and inefficiency within the software industry was akin to the house building industry. I&amp;#39;m sure in some respects he is right, but in a more fundamental way I disagree.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;An average layman off the street hiring a builder can ask them to build a wall. The average layman can see if the wall isn&amp;#39;t straight, the average layman can see when bricks are not aligned, they can see when a house is built to a high quality finish, where attention has been paid to detail. They may not be able to see if the builder has been deceitful by using substandard materials or hiding shortcuts, but a few hundred pounds to a surveyor will tell them all they need to know.&lt;/p&gt;
&lt;p&gt;Even the most technical of software management cannot tell if a basic 5 line piece of code is well written or not, let alone an application comprising many millions of lines of code. The best of them cannot even tell a &amp;quot;good&amp;quot; user experience from a &amp;quot;bad&amp;quot; one. It is almost accepted wisdom now that all developers write bad code, that all software is buggy, and that software projects never deliver what they promise.&lt;/p&gt;
&lt;p&gt;It is this problem that needs to be overcome ... it is easy to spend a lifetime in a development career, without ever having written a single line of even average quality code. There is very little visibility to non-developers.&lt;/p&gt;
&lt;p&gt;However, I assert the problem is that development is largely a creative skill, not a technical one. And creative skills are nearly impossible to quantify - you know when you like a piece of artwork, but you cannot say why in a way that means anything to anyone else. I cannot prove I am worth my daily rate, other than by people trusting me.&lt;/p&gt;
&lt;p&gt;With that kind of stumbling block, the best we can do is to rely upon automated tests, continuous integration, and Agile methodologies to at least make us more accountable, even if we are still unquantifiable.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=41878" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Practices+and+Principles/default.aspx">Practices and Principles</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Rants/default.aspx">Rants</category></item><item><title>Recovering a Project with ASP.NET MVC and Agile </title><link>http://devlicio.us/blogs/casey/archive/2008/08/13/recovering-a-project-with-asp-net-mvc-and-agile.aspx</link><pubDate>Wed, 13 Aug 2008 06:35:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:41809</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=41809</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=41809</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/08/13/recovering-a-project-with-asp-net-mvc-and-agile.aspx#comments</comments><description>&lt;p&gt;I recently got brought on board to a new client where, true to form, a project was in&amp;nbsp;a state of failure - everybody sort of knew it, but nobody would say it out loud.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What Was Going Wrong?&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;After my initial assessment, I made a quick decision that the major thing holding everyone back was an early decision to use MOSS 2007 to host an external website, and as the primary content management system. This wouldn&amp;#39;t have been a totally bad decision, if the team had a lot of good MOSS 2007 experience on board, but unfortunately they were learning as they went. If there is one thing that really doesn&amp;#39;t work well in MOSS it is a &amp;quot;lets just start and change it as we learn and go along&amp;quot; approach. MOSS takes a fair amount of careful up front analysis and planning to get right, and has enough permeutations and &amp;quot;gotchas&amp;quot; to require some good experience on the team before starting. Otherwise you can rapidly end up with a &lt;a class="" href="http://en.wikipedia.org/wiki/Big_ball_of_mud"&gt;big ball of mud&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So we took the decision that using MOSS was a major stumbling block, and this had to be removed from the equation. Of course it *could* have all been done in MOSS, but it wasn&amp;#39;t going to happen in the time left. There was also a small &amp;quot;jedi mind trick&amp;quot; involved too ... people had become so focused on the SharePoint &amp;quot;way&amp;quot; that they could no longer see the bigger picture.&lt;/p&gt;
&lt;p&gt;The decision was made to separate the public application away from MOSS, and to write it as a bespoke system. MOSS would still be used internally for document collaboration (which is where the strength of MOSS lies), and later on for publishing that information to the web site.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Software Stack&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;After some fast prototyping, some instinct based decisions, and a bit of faith, I finally decided on the following software stack to write the application:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;&lt;a class="" href="http://www.asp.net/mvc/"&gt;ASP.NET MVC&lt;/a&gt;&amp;nbsp;(&lt;a class="" href="http://www.codeplex.com/aspnet/Wiki/View.aspx?title=MVC&amp;amp;referringTitle=Home"&gt;preview 4&lt;/a&gt;)&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;a class="" href="http://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;a class="" href="http://www.castleproject.org/activerecord/index.html"&gt;Castle ActiveRecord&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;a class="" href="http://www.castleproject.org/container/index.html"&gt;Castle Windsor&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;a class="" href="http://ayende.com/wiki/Rhino+Commons.ashx"&gt;Rhino Commons&lt;/a&gt; (IRepository, ARRepository, UnitOfWork)&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;a class="" href="http://logging.apache.org/log4net/index.html"&gt;log4net&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Some of these were fairly safe choices, I have used them before, or they are tried and tested in the field. But obviously the major exception to that rule was ASP.NET MVC&lt;/p&gt;
&lt;p&gt;I very briefly considered Monorail, but it does not have the tooling support or documentation support of ASP.NET MVC, and going forwards Monorail is likely to dwindle whilst ASP.NET MVC will only grow.&lt;/p&gt;
&lt;p&gt;I also considered writing a Webforms application, and using MVP to split the UI from the logic, but this approach required a fair ramp up from the developers, and had too many possible variations to try and coax people into the right appraoch.&lt;/p&gt;
&lt;p&gt;ASP.NET MVC therefore would provide a degree of familiarity to the ASP.NET developers we have in the team, whilst providing a clean separation of responsibilities. The only question was stability, which after asking around seemed not to be an issue, despite being only at preview stage (something MS haven&amp;#39;t done before but is very welcome here) nobody reported any problems.&lt;/p&gt;
&lt;p&gt;By changing pretty much every element of the software stack we were using the team&amp;nbsp;has been&amp;nbsp;revitalised, and has approached the project with renewed vigor and enthusiasm. They get to learn some new things for their CV (pretty much none of them have used any of the new comnponents), and due to the amount of &amp;quot;magic&amp;quot; that things like Rhino and Windsor introduce they could get on with writing real functionality almost from day one.&lt;/p&gt;
&lt;p&gt;I am very impressed by how fast the developers have picked up MVC, here a large amount of credit goes to MS for making a very usable, approachable, and simple framework that does exactly what it needs to, and very little more.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Making it Build With Continuous Integration&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When&amp;nbsp;I arrived there was no project in place. Nothing, nada. I could not pull the project, build it and see it work. As everything was being done in MOSS people were writing projects for each small bit of fucntionality, and manually copying assemblies into a single MOSS deployment. And the only source control that existed was Visual Source Safe.&amp;nbsp;To say the least, this was scary.&lt;/p&gt;
&lt;p&gt;So the first thing I did here was to install &lt;a class="" href="http://www.visualsvn.com/server/"&gt;VisualSVN&lt;/a&gt;&amp;nbsp;and &lt;a class="" href="http://www.jetbrains.com/teamcity/"&gt;TeamCity&lt;/a&gt; and get a build server running. After setting up a single solution with all the relevant projects included, we now have a build that operates on every check in, and it automatically displays on a web site for everyone internally to see the progress. On the dev machines we installed &lt;a class="" href="http://tortoisesvn.tigris.org/"&gt;Tortoise SVN&lt;/a&gt; and &lt;a class="" href="http://ankhsvn.open.collab.net/"&gt;Ankh SVN&lt;/a&gt;, Ankh now seems a lot more stable in version 2, but has some irritating quirks still - it is however much better than any MS source control plugin, and falling back to Tortoise almost always fixes the problem.&lt;/p&gt;
&lt;p&gt;We also installed the trial version of &lt;a class="" href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt; on the dev machines. None of the people here had used it before, but within only a few days we were hearing a lot of &amp;quot;oh wow&amp;quot;, &amp;quot;that&amp;#39;s amazing&amp;quot;, and &amp;quot;that used to take me so long to do&amp;quot; ... in a week or two we will have to buy licences, but I think it has more than justified itself to the development team.&lt;/p&gt;
&lt;p&gt;The URL of the build site was distributed to the business users, and now they take an active interest in telling me the &amp;quot;walking skeleton&amp;quot; is a &amp;quot;pile of bones&amp;quot; when someone changes the DB loging details last thing at night :) &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changing the Process&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Also evident was that the approach that was being taken to the project was classic waterfall, along with a mixture of daily constantly changing and fluctuating requests and requirements. Communication was good with daily meetings, but the same things seemed to be repeated at each.&lt;/p&gt;
&lt;p&gt;So another bold decision I took was to approach this as a far more Agile project - using some elements of XP.&lt;/p&gt;
&lt;p&gt;I threw out the gant chart - much to the dismay of the project manager - and started writing up story cards, which promptly got placed on a commandeered wall. The project manager now has these story cards listed in an Excel spreadsheet so that he and the people he reports to can see exaclty where things are in a palatable form, but the wall remains the &amp;quot;one true master&amp;quot;&lt;/p&gt;
&lt;p&gt;We changed the 8.30am sit down meeting to a 9.30am stand up meeting, and have been trying to enforce a fast &amp;quot;what I did yesterday, what I will do today, what is holding me up&amp;quot; approach to stop us getting dragged down into details.&lt;/p&gt;
&lt;p&gt;We now have a lot more communication between developers as a result of this, and the business representatives are feeling very involved. There is still a degree of trepidation around what will be delivered, my protests of &amp;quot;you can see it as it goes along&amp;quot; and &amp;quot;it will be done when it will be done&amp;quot; are proving quite hard to swallow, but I think everyone understands there is no magic pill here and we just have to judge it step by step.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Proof Will Be in the Pudding&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So some good early steps have been taken. I cannot say the project is back on track, but everyone is now far more involved, has far more enthusiasm, and can see something starting to take shape. The perceived deadline of a few weeks from now is unlikely to be met with a fully functional site, but as &amp;quot;fully functional&amp;quot; is only vaguely defined, we are aiming to have something that is &amp;quot;good enough&amp;quot; by then, and then to make it better as people feed back into the process.&lt;/p&gt;
&lt;p&gt;So far a major success on the approach, now to see if we can turn that into a successfully delivered solution!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=41809" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Practices+and+Principles/default.aspx">Practices and Principles</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Rants/default.aspx">Rants</category><category domain="http://devlicio.us/blogs/casey/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Featured/default.aspx">Featured</category></item><item><title>Logging Without Using Castle Windsor and the Logging Facility</title><link>http://devlicio.us/blogs/casey/archive/2008/06/20/logging-without-using-castle-windsor-and-the-logging-facility.aspx</link><pubDate>Fri, 20 Jun 2008 07:02:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:41043</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=41043</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=41043</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/06/20/logging-without-using-castle-windsor-and-the-logging-facility.aspx#comments</comments><description>&lt;p&gt;As the discussion on the altdotnet list continued (&lt;a class="" href="http://devlicio.us/blogs/casey/archive/2008/06/18/logging-with-castle-windsor-the-logging-facility-and-log4net.aspx"&gt;some of it around my blog yesterday&lt;/a&gt;), it became apparent that some people didn&amp;#39;t want to use an IoC container - but more confusing was that their objection to the whole pattern was that they thought the IoC container in here meant I was writing different code because I was using an IoC container. In fact nothing could be further from the truth - my service class would be identical in code, regardless of whether I used a container, or a factory, or any other construction on my object.&lt;/p&gt;
&lt;p&gt;Let us look at the proposed service class again, a little expanded from the last example to show a bit more detail:&lt;/p&gt;
&lt;p&gt;
&lt;style&gt;.csharpcode {
	FONT-SIZE: small; COLOR: black; FONT-FAMILY: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace; BACKGROUND-COLOR: #ffffff
}
.csharpcode PRE {
	FONT-SIZE: small; COLOR: black; FONT-FAMILY: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace; BACKGROUND-COLOR: #ffffff
}
.csharpcode PRE {
	MARGIN: 0em
}
.csharpcode .rem {
	COLOR: #008000
}
.csharpcode .kwrd {
	COLOR: #0000ff
}
.csharpcode .str {
	COLOR: #006080
}
.csharpcode .op {
	COLOR: #0000c0
}
.csharpcode .preproc {
	COLOR: #cc6633
}
.csharpcode .asp {
	BACKGROUND-COLOR: #ffff00
}
.csharpcode .html {
	COLOR: #800000
}
.csharpcode .attr {
	COLOR: #ff0000
}
.csharpcode .alt {
	MARGIN: 0em; WIDTH: 100%; BACKGROUND-COLOR: #f4f4f4
}
.csharpcode .lnum {
	COLOR: #606060
}
&lt;/style&gt;
&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyService : IMyService

    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; ILogger logger;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; ILogger Logger
        {
            get
            {
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (logger == &lt;span class="kwrd"&gt;null&lt;/span&gt;) logger = NullLogger.Instance;
                &lt;span class="kwrd"&gt;return&lt;/span&gt; logger;
            }
            set { logger = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
        }


        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoMyThing()
        {
            &lt;span class="rem"&gt;// Do something here&lt;/span&gt;
            Logger.Debug(&lt;span class="str"&gt;&amp;quot;Hello&amp;quot;&lt;/span&gt;);
        }
    }&lt;/pre&gt;
&lt;style&gt;.csharpcode {
	FONT-SIZE: small; COLOR: black; FONT-FAMILY: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace; BACKGROUND-COLOR: #ffffff
}
.csharpcode PRE {
	FONT-SIZE: small; COLOR: black; FONT-FAMILY: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace; BACKGROUND-COLOR: #ffffff
}
.csharpcode PRE {
	MARGIN: 0em
}
.csharpcode .rem {
	COLOR: #008000
}
.csharpcode .kwrd {
	COLOR: #0000ff
}
.csharpcode .str {
	COLOR: #006080
}
.csharpcode .op {
	COLOR: #0000c0
}
.csharpcode .preproc {
	COLOR: #cc6633
}
.csharpcode .asp {
	BACKGROUND-COLOR: #ffff00
}
.csharpcode .html {
	COLOR: #800000
}
.csharpcode .attr {
	COLOR: #ff0000
}
.csharpcode .alt {
	MARGIN: 0em; WIDTH: 100%; BACKGROUND-COLOR: #f4f4f4
}
.csharpcode .lnum {
	COLOR: #606060
}
&lt;/style&gt;
&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IMyService
    {
        &lt;span class="kwrd"&gt;void&lt;/span&gt; DoMyThing();
    }&lt;/pre&gt;
&lt;p&gt;This service class is rather unimaginatively named, but has the basic parts in place. It has an optional ILogger property, and a method to DoMyThing(). One important thing to note is that the interface does not have an ILogger property.&lt;/p&gt;
&lt;p&gt;So if we don&amp;#39;t use an IoC container, we need some way to create instance of this class. The &amp;quot;old fashioned&amp;quot; way would use the new keyword, but this leads to all sorts of maintenance problems later on, and so we prefer to use some other kind of construction pattern, in this case a Factory, so here is our &amp;quot;application&amp;quot;, albeit rather simple:&lt;/p&gt;
&lt;p&gt;
&lt;style&gt;.csharpcode {
	FONT-SIZE: small; COLOR: black; FONT-FAMILY: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace; BACKGROUND-COLOR: #ffffff
}
.csharpcode PRE {
	FONT-SIZE: small; COLOR: black; FONT-FAMILY: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace; BACKGROUND-COLOR: #ffffff
}
.csharpcode PRE {
	MARGIN: 0em
}
.csharpcode .rem {
	COLOR: #008000
}
.csharpcode .kwrd {
	COLOR: #0000ff
}
.csharpcode .str {
	COLOR: #006080
}
.csharpcode .op {
	COLOR: #0000c0
}
.csharpcode .preproc {
	COLOR: #cc6633
}
.csharpcode .asp {
	BACKGROUND-COLOR: #ffff00
}
.csharpcode .html {
	COLOR: #800000
}
.csharpcode .attr {
	COLOR: #ff0000
}
.csharpcode .alt {
	MARGIN: 0em; WIDTH: 100%; BACKGROUND-COLOR: #f4f4f4
}
.csharpcode .lnum {
	COLOR: #606060
}
&lt;/style&gt;
&lt;pre class="csharpcode"&gt;   &lt;span class="kwrd"&gt;class&lt;/span&gt; Program
    {
        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)
        {
            IMyService service = MyServiceFactory.Create();
            &lt;span class="rem"&gt;// Note that IMyService does not have a Logger property ...&lt;/span&gt;
            service.DoMyThing();
        }
    }&lt;/pre&gt;
&lt;p&gt;The thing to note here is that we only refer to the MyService class via the IMyService interface, so our consuming application does not know the service has a Logger property, nor does it care. In the Castle Windsor version earlier the line MyServiceFactory.Create() would have been something like IoC.Resolve&amp;lt;IMyService&amp;gt;() - but apart from that the consumer of the service has no idea how the object is being constructed, and nor does it care.&lt;/p&gt;
&lt;p&gt;For the sake of this example, here is some dummy code to represent our Logging classes. In the Castle Windsor case we use the ILogger in the Castle assemblies, we could also use that in this example, but would probably want to write our own if we didn&amp;#39;t want to use any of the Castle code.&lt;/p&gt;
&lt;p&gt;
&lt;style&gt;.csharpcode {
	FONT-SIZE: small; COLOR: black; FONT-FAMILY: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace; BACKGROUND-COLOR: #ffffff
}
.csharpcode PRE {
	FONT-SIZE: small; COLOR: black; FONT-FAMILY: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace; BACKGROUND-COLOR: #ffffff
}
.csharpcode PRE {
	MARGIN: 0em
}
.csharpcode .rem {
	COLOR: #008000
}
.csharpcode .kwrd {
	COLOR: #0000ff
}
.csharpcode .str {
	COLOR: #006080
}
.csharpcode .op {
	COLOR: #0000c0
}
.csharpcode .preproc {
	COLOR: #cc6633
}
.csharpcode .asp {
	BACKGROUND-COLOR: #ffff00
}
.csharpcode .html {
	COLOR: #800000
}
.csharpcode .attr {
	COLOR: #ff0000
}
.csharpcode .alt {
	MARGIN: 0em; WIDTH: 100%; BACKGROUND-COLOR: #f4f4f4
}
.csharpcode .lnum {
	COLOR: #606060
}
&lt;/style&gt;
&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; log4netLogger : ILogger
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Debug(&lt;span class="kwrd"&gt;string&lt;/span&gt; message)
        {
            &lt;span class="rem"&gt;// Send to log4net here&lt;/span&gt;
        }
    }



    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; ILogger
    {
        &lt;span class="kwrd"&gt;void&lt;/span&gt; Debug(&lt;span class="kwrd"&gt;string&lt;/span&gt; message);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; NullLogger
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; ILogger Instance;
    }&lt;/pre&gt;
&lt;p&gt;Of course our ILogger will probably have a lot of other signatures defined, but this will do for now.&lt;/p&gt;
&lt;p&gt;So now the only part of the equation missing is the actual factory we are going to use to replace the IoC container.&lt;/p&gt;
&lt;p&gt;
&lt;style&gt;.csharpcode {
	FONT-SIZE: small; COLOR: black; FONT-FAMILY: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace; BACKGROUND-COLOR: #ffffff
}
.csharpcode PRE {
	FONT-SIZE: small; COLOR: black; FONT-FAMILY: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace; BACKGROUND-COLOR: #ffffff
}
.csharpcode PRE {
	MARGIN: 0em
}
.csharpcode .rem {
	COLOR: #008000
}
.csharpcode .kwrd {
	COLOR: #0000ff
}
.csharpcode .str {
	COLOR: #006080
}
.csharpcode .op {
	COLOR: #0000c0
}
.csharpcode .preproc {
	COLOR: #cc6633
}
.csharpcode .asp {
	BACKGROUND-COLOR: #ffff00
}
.csharpcode .html {
	COLOR: #800000
}
.csharpcode .attr {
	COLOR: #ff0000
}
.csharpcode .alt {
	MARGIN: 0em; WIDTH: 100%; BACKGROUND-COLOR: #f4f4f4
}
.csharpcode .lnum {
	COLOR: #606060
}
&lt;/style&gt;
&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyServiceFactory
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IMyService Create()
        {
            MyService service = &lt;span class="kwrd"&gt;new&lt;/span&gt; MyService();
            service.Logger = LoggingServiceFactory.Create();
            &lt;span class="rem"&gt;// Do other initialisation here&lt;/span&gt;
            &lt;span class="kwrd"&gt;return&lt;/span&gt; service;
        }

    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; LoggingServiceFactory
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; ILogger Create()
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; log4netLogger();
        }
    }&lt;/pre&gt;
&lt;p&gt;That is all there is to it. It may seem like a lot of code to do a simple thing, and it is in a way - I would really try to avoid writing all this when Castle Windsor or an other IoC container will do all this for me - but it preserves one very important principle - the MyService class is totally clean, it does not have any knowledge of how it was constructed, and it does not know how it gets a logging class, it just knows that it can try and log something, and if it was meant to log, then it will.&lt;/p&gt;
&lt;p&gt;This is the principle of Seperation of Concerns at work - the class has only one concern, and it isn&amp;#39;t how to create a logger object.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=41043" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Practices+and+Principles/default.aspx">Practices and Principles</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Sample+Code/default.aspx">Sample Code</category><category domain="http://devlicio.us/blogs/casey/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Windsor/default.aspx">Windsor</category></item><item><title>The Language of Mocks (or is that Test Doubles)</title><link>http://devlicio.us/blogs/casey/archive/2008/06/11/the-language-of-mocks-or-is-that-test-doubles.aspx</link><pubDate>Wed, 11 Jun 2008 09:25:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:40953</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=40953</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=40953</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/06/11/the-language-of-mocks-or-is-that-test-doubles.aspx#comments</comments><description>&lt;p&gt;&lt;a class="" href="http://codebetter.com/blogs/ian_cooper/"&gt;Ian Cooper&lt;/a&gt; brought up an interesting point on the altdotnet mailing list recently, around the language used to describe Mocks, or more accurately his preference for the term Test Double over my use of the generic term Mock.&lt;/p&gt;
&lt;p&gt;In most areas of development I can often be considered a language perfectionist, for example calling something a Unit Test when it is *clearly* an Integration Test drives me nuts - but when it comes to Mocks, Stubs, Fakes, Spys, or the rather more generic Test Doubles ... I just can&amp;#39;t get passionate about the language.&lt;/p&gt;
&lt;p&gt;This all started a while ago, when people started using the term mock, but really it wasn&amp;#39;t a mock&amp;nbsp;- or more often they used the term mock when referring to what many mock frameworks call a Strict Mock, just one type of mock.&lt;/p&gt;
&lt;p&gt;Martin Fowler &lt;a class="" href="http://www.martinfowler.com/bliki/TestDouble.html"&gt;long ago posted&lt;/a&gt; on a clarification of the terminology around mocking, and xUnitPatterns has a &lt;a class="" href="http://xunitpatterns.com/Test%20Double.html"&gt;fuller description&lt;/a&gt;. The distinction that Gerard Meszaros introduced was to use the term Test Double to describe all of these things we use to help us test our code. Fakes, Spys, Mocks, Dummys ... all just a type of Test Double.&lt;/p&gt;
&lt;p&gt;Now language is important. Very important. As Ian pointed out in his email, most arguments centre around a misunderstanding of the terminology involved - I&amp;#39;m sure the world would be a nicer place if language was universal and could not be interpreted differently by different people, but then it would be a linguistically poorer place for it too.&lt;/p&gt;
&lt;p&gt;In development, language is something that is vital to good communication of what are often very complex technical concepts. We evolved the languages of patterns and principles to allow us to avoid confusion and misunderstandings, and most areas of development have their own specific language terminology.&lt;/p&gt;
&lt;p&gt;But, with this one area of testing I have a problem with the terminology, because the term that I hear from developers on a daily basis is &amp;quot;mocking&amp;quot;, not &amp;quot;test doubles&amp;quot;. And when terminology enters the common language, it is very hard to replace it with a new term just because you prefer it. I&amp;#39;m sure that Test Double describes the concept better, and I&amp;#39;m sure that it is important to have some distinction between Mocks and Fakes, but in my experience, that is not how developers refer to these things.&lt;/p&gt;
&lt;p&gt;It is much easier to say &amp;quot;we can mock this out&amp;quot; than it is to say &amp;quot;we can create a test double here&amp;quot;, the first is just more natural in the English language. So the term &amp;quot;mock&amp;quot; has become almost a defacto term for what Martin Fowler et al refer to as a Test Double, whilst also being a Mock with&amp;nbsp;a capital M for describing the Mock that most mock frameworks create.&lt;/p&gt;
&lt;p&gt;So, much as I might like to be a language perfectionist on this one, I tend to just use the term mock, and leave the decision as to whether it is a Mock, Fake, Stub or Whatever to the point I actually code it. So far nobody has misconstrued Mock to mean &amp;quot;you must use a mocking framework&amp;quot;, or at least not anyone to whom the concepts of mocking are not entirely new anyway, in which case much more clarification is needed in any case.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=40953" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/TDD/default.aspx">TDD</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Mocking/default.aspx">Mocking</category></item><item><title>ReSharper 4.0 Has Apparently Gone to Beta!</title><link>http://devlicio.us/blogs/casey/archive/2008/05/22/resharper-4-0-has-apparently-gone-to-beta.aspx</link><pubDate>Thu, 22 May 2008 11:05:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:40704</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=40704</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=40704</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/05/22/resharper-4-0-has-apparently-gone-to-beta.aspx#comments</comments><description>&lt;p&gt;Yes, you heard me! Apparently&lt;a class="" href="http://resharper.blogspot.com/2008/05/resharper-4-beta.html"&gt; ReSharper 4.0 is now in Beta status&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This has got to be one of the longest upgrades in development history - I was beginning to think that ReSharper 4 was never going to be released! &lt;/p&gt;
&lt;p&gt;I love ReSharper, and the EAP program has given me a &amp;quot;free&amp;quot; licence for it for months now, but it was getting a little tiresome waiting - but now the end is in sight!&amp;nbsp; We all appreciate that support for C#3.0 was non-trivial, but much longer and they would have needed to think about supporting C# 4.0 :)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=40704" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Practices+and+Principles/default.aspx">Practices and Principles</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/ReSharper/default.aspx">ReSharper</category></item><item><title>What Determines High Quality Code?</title><link>http://devlicio.us/blogs/casey/archive/2008/05/16/what-determines-high-quality-code.aspx</link><pubDate>Fri, 16 May 2008 13:59:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:40579</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=40579</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=40579</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/05/16/what-determines-high-quality-code.aspx#comments</comments><description>&lt;p&gt;Code quality is an abstract concept again, and can be defined may ways depending on how you perceive quality. A good discussion of the many aspects of code quality can be found on Wikipedia at &lt;a href="http://en.wikipedia.org/wiki/Software_quality"&gt;http://en.wikipedia.org/wiki/Software_quality&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some general high level objectives for software quality could be considered to be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Conformance to requirements&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Correctness&lt;/li&gt;
&lt;li&gt;Completeness&lt;/li&gt;
&lt;li&gt;Absence of Bugs&lt;/li&gt;
&lt;li&gt;Fault tolerance&lt;/li&gt;
&lt;li&gt;Extensibility&lt;/li&gt;
&lt;li&gt;Maintainability&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;At a code quality level, some general good guidelines would be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Readability&lt;br /&gt;&lt;/b&gt;- Code should be simple to read, even without comments&lt;br /&gt;- Class, method, and variable names should be expressive and unambiguous&lt;br /&gt;- Functional intent should be easily understood&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ease of Maintenance, Testing and Debugging&lt;/b&gt;&lt;br /&gt;The degree of effort required to maintain, test and debug an application is a strong indication of the quality of the code and architecture. As the great majority of the cost of an application is actually composed of these three activities, these should be primary considerations&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Low Complexity&lt;/b&gt;&lt;br /&gt;Complex code is rarely complex because the business functionality it implements is complex. Most software complexity comes through poorly designed and implemented code, over analysis of the problem, or adding additional functionality for requirements that do not yet exist.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Low Resource Consumption&lt;/b&gt;&lt;br /&gt;Poorly written code will not take account of resource usage, for example it will not cache information it could cache, or it will create new objects when it did not need to. These issues lead to hard to maintain applications when deployed and used.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;To achieve these objectives, some basic principles of development and design can be applied. These have been referenced elsewhere, but are repeated here for clarity:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Single Responsibility Principle&lt;br /&gt;&lt;/b&gt;There should never be more than one reason for a class to change&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Liskov Substitution Principle&lt;/b&gt;&lt;br /&gt;Methods that use references to base classes should be able to use derived classes without knowing they are doing so&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Open Closed Principle&lt;/b&gt;&lt;br /&gt;Software entities (classes, modules, methods) should be open for extension but closed for modification&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Interface Segregation Principle&lt;/b&gt;&lt;br /&gt;Clients should not be forced to depend upon interfaces they do not use&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Dependency Inversion Principle&lt;br /&gt;&lt;/b&gt;High level modules should not depend upon low level modules, they should both depend upon abstractions&lt;br /&gt;Abstractions should not depend upon details, details should depend upon abstractions&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Principle of Least Surprise (sometimes known as Principle of Least Astonishment)&lt;/b&gt;&lt;br /&gt;The result of performing some operation should be obvious, consistent, and predictable, based upon the name of the operation and other clues&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Separation of Concerns&lt;/b&gt;&lt;br /&gt;The application should be broken into components that overlap in functionality as little as possible &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;An assessment of code against these core principles should give a developer a good basis for assessment of the quality of a code base.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=40579" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Practices+and+Principles/default.aspx">Practices and Principles</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Rants/default.aspx">Rants</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>Statistics and How They Lie</title><link>http://devlicio.us/blogs/casey/archive/2008/05/16/statistics-and-how-they-lie.aspx</link><pubDate>Fri, 16 May 2008 09:49:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:40577</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=40577</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=40577</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/05/16/statistics-and-how-they-lie.aspx#comments</comments><description>&lt;p&gt;&lt;b&gt;&lt;i&gt;Industry experience suggests that the design of metrics will encourage certain kinds of behaviour from the people being measured. The common phrase applied is &amp;quot;you get what you measure&amp;quot; (or &amp;quot;be careful what you wish for&amp;quot;).&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3&gt;A Brief Explanation of Cyclomatic Complexity and Code Coverage&lt;/h3&gt;
&lt;p&gt;Cyclomatic complexity is a measure of the number of possible paths through a piece of code. This is a relatively easy measurement to make, and code analysis tools can give you this figure directly. As cyclomatic complexity is directly analogous to the number of paths through the code, it is also a direct count of the number of unit tests required as a &lt;i&gt;minimum&lt;/i&gt; to test all the code paths.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A cyclomatic complexity of 1-10 is a simple piece of code that is easily maintainable.&lt;/li&gt;
&lt;li&gt;A cyclomatic complexity of 11-20 is a moderately complex piece of code, that is relatively easy to maintain.&lt;/li&gt;
&lt;li&gt;A cyclomatic complexity of 21-50 would indicate either a highly complex or high risk piece of code. The functionality of the code observed indicates it is in no way complex, and therefore it must fall into the high risk category.&lt;/li&gt;
&lt;li&gt;A cyclomatic complexity of 51 and above indicates un-testable code, and a very high risk to the project.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Code coverage measures the number of paths through your code that had at least one execution when unit tests were run. It does not however give any real quality measure against the value of those tests, or the actual quality of those tests.&lt;/p&gt;
&lt;p&gt;It is actually easier to get better coverage results from writing poor code. The poorer the quality of your code and of your tests, the easier it is to achieve high coverage figures.&lt;/p&gt;
&lt;p&gt;See also: &lt;a class="" href="http://devlicio.us/blogs/casey/archive/2008/05/15/measuring-progress.aspx"&gt;Measuring Progress&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=40577" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Practices+and+Principles/default.aspx">Practices and Principles</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Rants/default.aspx">Rants</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>Lines of Code as a Measure of Progress</title><link>http://devlicio.us/blogs/casey/archive/2008/05/16/lines-of-code-as-a-measure-of-progress.aspx</link><pubDate>Fri, 16 May 2008 08:51:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:40578</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=40578</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=40578</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/05/16/lines-of-code-as-a-measure-of-progress.aspx#comments</comments><description>&lt;p&gt;Some reports will highlight lines of code as a figure to attach some relevance to, and these become measures used to establish progress.&lt;/p&gt;
&lt;p&gt;These are possibly the most misleading figures to use, in fact almost always within a well designed application and code base, the reverse is true.&lt;/p&gt;
&lt;p&gt;Good code tends to be more concise than poor code, and therefore it is less lines of code. &lt;/p&gt;
&lt;p&gt;Good code also tends to have high levels of code reuse; one of the primary refactoring exercises is removing code duplication. This obviously again leads to a lower number of lines of code. However, the concept of reuse can also be used to increase lines of code and reduce quality in the hands of inexperienced developers.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;An example:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The following pieces of code are all functionally identical:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Version One (4 lines):&lt;/b&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MyMethod()
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (myObject == &lt;span class="kwrd"&gt;null&lt;/span&gt;) doSomething();
        }
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Version Two (8 lines):&lt;/b&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MyMethod()
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (Assert(myObject)) doSomething();
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Assert(&lt;span class="kwrd"&gt;object&lt;/span&gt; theObject)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; theObject == &lt;span class="kwrd"&gt;null&lt;/span&gt;;
        }
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Version Three (8 lines of code):&lt;/b&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MyMethod()
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (Assert(myObject))
            {
                doSomething();
            }
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Assert(&lt;span class="kwrd"&gt;object&lt;/span&gt; theObject)
        {
            &lt;span class="kwrd"&gt;bool&lt;/span&gt; theResult = (theObject==&lt;span class="kwrd"&gt;null&lt;/span&gt;);
            &lt;span class="kwrd"&gt;return&lt;/span&gt; theResult;
        }
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Version Four (20 lines of code):&lt;/b&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MyMethod()
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (Assert(myObject))
            {
                doSomething();
            } 
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Assert(&lt;span class="kwrd"&gt;object&lt;/span&gt; theObject)
        {
            &lt;span class="kwrd"&gt;bool&lt;/span&gt; theResult;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (theObject==&lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                theResult = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                theResult = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            }
            &lt;span class="kwrd"&gt;return&lt;/span&gt; theResult;=
        }
&lt;/pre&gt;
&lt;p&gt;As it turns out, the version of that code with the highest quality is Version One, coming in at 4 lines of code total, and actually only 1 line of code that does anything. Version Four has 5 times the number of lines of code as a base guideline, but has 8 times the lines of code if only actual statements are counted. Version Four is coincidentally the poorest quality version of the functionality.&lt;/p&gt;
&lt;p&gt;So if lines of code are a measure of progress, a developer can, consciously or subconsciously, increase their visible progress, by writing lower quality and less maintainable code.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;How About Measuring Decreasing Lines of Code as Success?&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Depending on how you are measuring lines of code, even looking for trends in reduction of lines of code can be considered the wrong approach. For example, now if I concatenate multiple statements into a single terse, unreadable and un-maintainable statement, I can reduce my line count.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;An example:&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Version One (8 lines):&lt;/b&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; MyMethod(&lt;span class="kwrd"&gt;string&lt;/span&gt; myString, &lt;span class="kwrd"&gt;int&lt;/span&gt; result)
   {
       &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt; SmallIncrease = 1;
       &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt; LargeIncrease = 2;

       &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(myString))
           result = result + SmallIncrease;
       &lt;span class="kwrd"&gt;else&lt;/span&gt;
           result = result + LargeIncrease;
      &lt;span class="kwrd"&gt;return&lt;/span&gt; result;
   }
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Version Two (4 lines):&lt;/b&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; MyMethod(&lt;span class="kwrd"&gt;string&lt;/span&gt; myString, &lt;span class="kwrd"&gt;int&lt;/span&gt; result)
   {
      &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(myString) ? result+1 result+2;
   }
&lt;/pre&gt;
&lt;p&gt;In this example, Version One of the code is simpler to read, but is twice as many lines of code. This is also a very simple example; a more complex example would be even more drastic in the difference between the numbers of lines of code in the two methods.&lt;/p&gt;
&lt;p&gt;Within this simple example the first is much easier to read, understand, and therefore maintain. The second obfuscates the values of 1 and 2 in the calculation, and makes it harder to follow the execution path of the code.&lt;/p&gt;
&lt;p&gt;Arguably Version Two could be considered acceptable with some modifications (like the addition of the constants defined in Version One), however both of these piece of code will actually compile to identical binary code.&lt;/p&gt;
&lt;p&gt;In this case Version One is higher quality code as it is easier to understand its intention, and the ability to quickly read and understand intent is a major factor in determining the quality of code.&lt;/p&gt;
&lt;style&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: Consolas, &amp;quot;Courier New&amp;quot;, Courier, Monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}

.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=40578" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Practices+and+Principles/default.aspx">Practices and Principles</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Rants/default.aspx">Rants</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>Measuring Progress</title><link>http://devlicio.us/blogs/casey/archive/2008/05/15/measuring-progress.aspx</link><pubDate>Thu, 15 May 2008 08:48:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:40576</guid><dc:creator>Jak Charlton</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/rsscomments.aspx?PostID=40576</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/casey/commentapi.aspx?PostID=40576</wfw:comment><comments>http://devlicio.us/blogs/casey/archive/2008/05/15/measuring-progress.aspx#comments</comments><description>&lt;p&gt;&lt;b&gt;&lt;i&gt;&amp;quot;Working software is the primary measure of progress&amp;quot;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Fundamentally, there is no more valid measure for progress, than the working software itself. This only leaves open to discussion, the definition of &amp;quot;working software&amp;quot;.&lt;/p&gt;
&lt;h3&gt;Defining &amp;quot;Working Software&amp;quot;&lt;/h3&gt;
&lt;p&gt;The criterion for defining working software is obviously open to debate. A common definition is:&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Software can be called &amp;quot;working software&amp;quot; when it meets a defined set of business requirements and can be demonstrated to do so through testing.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;This is one reason why Agile processes put so much value on unit testing, these tests show very early on in the process that software is meeting business requirements, without the need to create a fully functional user testable application. These unit tests also allow demonstration at a fairly low level of granularity that code is meeting requirements, where a user facing application is dependent on too many factors to easily establish correctness.&lt;/p&gt;
&lt;h3&gt;So How Do We Measure Progress?&lt;/h3&gt;
&lt;p&gt;Based on this definition, our best way to measure progress and velocity on projects is to evaluate defined business requirements, against the code that is provided to meet those requirements.&lt;/p&gt;
&lt;p&gt;Code that is written, but is not yet functional and passing tests cannot be considered progress until it has been completed to a level as defined above.&lt;/p&gt;
&lt;p&gt;This then prioritises getting components of functionality completed early, rather than attempting to do all things simultaneously. &lt;/p&gt;
&lt;p&gt;The traditional &amp;quot;waterfall&amp;quot; approach to software development is to spread large amounts of functional requirements out amongst large teams, for example assigning each piece of functionality to a team member with an expected delivery date measured in weeks or months. This leads to very long cycles for delivery of something correlating to &amp;quot;working software&amp;quot;&lt;/p&gt;
&lt;p&gt;An Agile approach to the same problem is to focus the teams on only a small subset of that functionality, and to attempt to deliver it in a working and testable state in very short iterations. The degree of success with which they do this then becomes their &amp;quot;velocity&amp;quot;. The velocity can then be used as a predictor of future success rates and therefore of future timescales. This also allows a &amp;quot;fail fast&amp;quot; mentality, where it is better to hit problems early on and resolve them, rather than delay all the problems for as long as possible down the development path.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Therefore, the best way of measuring success is to do one thing at a time, do it well, ensure it works, ensure it meets criteria, ensure it can be tested, and then to replicate the things that went right on the next piece of functionality, and eliminate the things that did not go so well.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=40576" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/casey/archive/tags/Practices+and+Principles/default.aspx">Practices and Principles</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Agile/default.aspx">Agile</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Rants/default.aspx">Rants</category><category domain="http://devlicio.us/blogs/casey/archive/tags/Architecture/default.aspx">Architecture</category></item></channel></rss>