<?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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Planet TW</title>
	<link>http://blogs.thoughtworks.com/</link>
	<language>en</language>
	<description>Planet TW - http://blogs.thoughtworks.com/</description>

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/PlanetTw" type="application/rss+xml" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site.</feedburner:browserFriendly><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
	<title>Simon Brunning: Links for 2009-11-13 [del.icio.us]</title>
	<guid isPermaLink="false">http://del.icio.us/brunns#2009-11-13</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/2bubu_AUmVA/brunns</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://books.couchdb.org/relax/"&gt;CouchDB: The Definitive Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.guardian.co.uk/news/datablog/2009/nov/13/peak-oil-iea-uppsala?showallcomments=true#end-of-comments"&gt;Peak oil: What the data says&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.vmware.com/products/converter/"&gt;Convert Physical Machines to Virtual Machines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.markhneedham.com/blog/2009/04/13/tdd-balancing-dryness-and-readability/"&gt;TDD: Balancing DRYness and Readability&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Given, When, Then&lt;/li&gt;
&lt;li&gt;&lt;a href="http://birdhouse.org/blog/2009/11/11/drupal-or-django/"&gt;Drupal or Django? A Guide for Decision Makers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://news.discovery.com/space/the-lhc-black-hole-no-braner.html"&gt;Man-Made (But Very Tiny) Black Holes Possible&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.guardian.co.uk/news/datablog/2009/nov/13/information-beautiful-afghanistan"&gt;Information is not beautiful: Afghanistan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mediamolecule.com/2009/11/13/learn-about-logic-take-a-tour-of-logictech/"&gt;LBP - learn about Logic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Sat, 14 Nov 2009 08:00:00 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/SmallValuesOfCool/~3/MBBaoAW6dHw/brunns</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009 - The Changing Learning Function: Rethinking how your organization works</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-5959228588151846711</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/skai2_384LY/devlearn-2009-changing-learning.html</link>
	<description>The last session from DevLearn 2009 that I sat through was the one by David Mallon from Bersin &amp;amp; Associates, called &lt;em&gt;"The Changing Learning Function: Rethinking how your organization works"&lt;/em&gt;. David was presenting empirical evidence from 798 Organisations and 40,000 training and HR business leaders and using Bersin's analysis about what the new face of the learning organisation should be like.&lt;br&gt;&lt;/br&gt;&lt;h3&gt;What I learnt&lt;/h3&gt;&lt;ul&gt;&lt;li&gt; Why are we talking about all of these new technologies? Its because business is changing and that's forcing businesses to rethink what we do in each of our departments and that includes learning and development, knowledge management, and the like. Are all the thinks we knew about our job really as good and are we using ourselves in the best way for our organisation?&lt;/li&gt;&lt;li&gt; The problem is context, not content. Its everyone's responsibility to deal with information and act on it. Everyone is a knowledge worker and the overwhelming amount of information floating around. Its tough to find the most useful information. &lt;/li&gt;&lt;li&gt; We need to reuse and have some set of standards to be successful. Frequent change of information makes it difficult to find the most current information. Inconsistency of information formats or sources makes it difficult to use and comprehend new info. &lt;/li&gt;&lt;li&gt; Learning professionals have the ability to create the context and the standards that organisations really need. &lt;/li&gt;&lt;li&gt; The ongoing role of a modern enterprise L&amp;amp;D function is two fold:&lt;ul&gt;&lt;li&gt; &lt;strong&gt;Deep Specialisation:&lt;/strong&gt;Focus on your company's niche. What's your competitive advantage? &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Learning Agility:&lt;/strong&gt; At an organisational level, how quickly can you add new skillsets, learn from your mistakes and create new capabilities.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; &lt;strong&gt;A change is needed:&lt;/strong&gt; Large and midsized organisations are still spending most of their learning time in their classrooms. Technology enabled learning is gaining strength each year, but very slowly. Having said this, most leaders believe that on the job experience, mentoring, projects, job rotation, and coaching are the most valuable learning approaches. 72% companies believe that the most valuable learning approaches are informal, yet only 30% of resources are focussed in that area! So, we need to optimise the informal learning in organisation and not just the classroom.&lt;/li&gt;&lt;li&gt; The modern learning organisation should be structured in the following framwework:&lt;ul&gt;&lt;li&gt; Your Learning Programs addressing your Audiences and Problems &lt;/li&gt;&lt;li&gt;Your Approaches and Architecture:&lt;ul&gt;&lt;li&gt; Formal Learning: 20% &lt;/li&gt;&lt;li&gt; Informal Learning: 80%. This includes&lt;ul&gt;&lt;li&gt; On-demand Learning: Elearning, help, search, books, etc&lt;/li&gt;&lt;li&gt; Social Learning: Blogs, wikis, forums, communities, social networks, etc. &lt;/li&gt;&lt;li&gt; Embedded Learning: All the ways that we learn inside work. eg: Performance Support, Feedback, Rotational Assignments, Course Corrections, Retrospectives, etc.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; The Disciplines that people need to master to adopt these approaches &lt;/li&gt;&lt;li&gt; The tools and technology that support these disciplines &lt;/li&gt;&lt;li&gt; But most importantly, beyond all of this, under the hood -- there's the culture of the organisation.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; The Modern Enterprise Learning Index (MELI) is a set of 10 indicators to determine readiness/ capacity to support learning agility and thrive in the face of informative change. (&lt;strong&gt;Internal Indicators:&lt;/strong&gt; Capacity Building, Business Analysis, Content Efficiency, Adaptation, Versatile) (&lt;strong&gt;External Indicators:&lt;/strong&gt; Business Driven, Talent Linked, Timely, Targetted, Proximal) &lt;/li&gt;&lt;li&gt; Retention after training events is high, but it drops over time and so does expertise. Learning is a process and not an event, so informal learning create a series of events that helps people learn over time. How about blending informality into formal learning by leveraging online communities, and by using tools such as Job Aids (Standard Work), Forums, EPSS, etc. David showed a case study from Nationwide insurance in how they blended informal learning around a large formal program to help a major capabilities shift for the company. IBM Blue Pages was another example that David showed as an enterprise wide collaboration system.&lt;/li&gt;&lt;li&gt; Coaching is a highly underestimated way of creating learning over time.&lt;/li&gt;&lt;li&gt; I loved the case study of BT that he showed where they were looking at Formal Learning supported by Social Learning, developed by anyone, using segments lasting minutes, delivered by anyone, given just in time, pulled and in real time and was dynamic and adhoc (long sentence, I know!) This apparently built reputation and people wanted to contribute to be known as "the guy". The community flags inappropriate content and there's hardly ever been anything that they had to pull out. &lt;/li&gt;&lt;li&gt; David lastly looked at the Disciplines we need to engage in as Learning professionals to make our organisations successful. He had culled this using data from the 10% of the most successful companies he had surveyed&lt;ul&gt;&lt;li&gt; &lt;strong&gt;Knowledge Management:&lt;/strong&gt; Develop overall strategies for capturing and harnessing the collective knowledge of an organisation.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;Business Intelligence/ Analytics&lt;/strong&gt; &lt;/li&gt;&lt;li&gt; &lt;strong&gt;Information Architecture:&lt;/strong&gt; Structuring information to make it easy to find. Stop paying attention to a single course, but pay more attention to the learning experience. This involves thinking spatially across contexts.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;Performance Consulting&lt;/strong&gt; &lt;/li&gt;&lt;li&gt; &lt;strong&gt;Development of Rich Media (information, visualisation, etc)&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; The role of a Training team: &lt;span style="font-style: italic;"&gt;"Center of Excellence for Learning in the organisation"&lt;/span&gt;. Focus on capabilities (preparing for tomorrow) as against skills (preparing for today).&lt;/li&gt;&lt;li&gt;New Roles in the learning organisation:&lt;ul&gt;&lt;li&gt; Performance Consultants &lt;/li&gt;&lt;li&gt; Instructional Designers &lt;ul&gt;&lt;li&gt; Work out in the biz, teaching others to structure knowledge; &lt;/li&gt;&lt;li&gt; Supervise SMEs. &lt;/li&gt;&lt;li&gt; Add additional disciplines to create environments &lt;/li&gt;&lt;li&gt; Be masters of the business &lt;/li&gt;&lt;li&gt; Measure approaches in business terms &lt;/li&gt;&lt;li&gt; View fast/ efficient business performance/ improvement as ultimate expression of their ablities.&lt;/li&gt;&lt;/ul&gt; &lt;/li&gt;&lt;li&gt; Content Developers &lt;/li&gt;&lt;li&gt; Multimedia Specialists &lt;/li&gt;&lt;li&gt; Information Architects &lt;/li&gt;&lt;li&gt; Editors/ Production Support &lt;/li&gt;&lt;li&gt; Community Management &lt;/li&gt;&lt;li&gt; Content Stewards &lt;/li&gt;&lt;li&gt; Moderators &lt;/li&gt;&lt;li&gt; Program Managers &lt;/li&gt;&lt;li&gt; SME's &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-5959228588151846711?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Sat, 14 Nov 2009 06:19:05 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/G_x4lVj_ONU/devlearn-2009-changing-learning.html</feedburner:origLink></item>
<item>
	<title>Mark Needham: Mercurial: hg bisec</title>
	<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=1822</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/oPTPoIFjyf4/</link>
	<description>&lt;p&gt;We've been using &lt;a href="http://mercurial.selenic.com/wiki/"&gt;Mercurial&lt;/a&gt; locally on the project I've been working on and &lt;a href="http://fragmental.tw/"&gt;Phil&lt;/a&gt; showed me a cool feature called '&lt;a href="http://mercurial.selenic.com/wiki/BisectExtension"&gt;bisec&lt;/a&gt;' a couple of weeks ago which can be helpful for working out which revision we managed to break our code in.&lt;/p&gt;
&lt;p&gt;It's been ported across from &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt; and is included in Mercurial from version 1.0.0 rather than just being an extension.&lt;/p&gt;
&lt;p&gt;From the bisec extension page:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
Its behaviour is fairly simple: it takes a first revision known to be correct (i.e. without the bug) and a last revision known to be bad (i.e. with the bug). The bisect extension ouputs a revision halfway between the good and the bad ones and lets you test it. If this revision is a good one, you mark it as good with hg bisect good, otherwise you mark it as bad with hg bisect bad. In both cases, bisect outputs a new revision to test, halfway between the good and the bad ones. You repeat until only one revision is left: the culprit.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The usage has changed a bit now that it's included as part of the initial download.&lt;/p&gt;
&lt;p&gt;I was working on something yesterday and checking in fairly regularly before realising that I'd broken something.&lt;/p&gt;
&lt;p&gt;I was fairly sure that the break had happened in the tip (revision 98) but I could only remember it definitely working in revision 96.&lt;/p&gt;
&lt;p&gt;I defined the good and bad revisions like this:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="text"&gt;hg bisec -b tip&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;


&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="text"&gt;hg bisec -g 96&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this case revision 97 was now checked out and I checked that the code was working with that revision before marking it:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="text"&gt;hg bisec -g&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It's now able to work out that the problem is in fact in revision 98:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="text"&gt;The first bad revision is:
changeset:   98:86260809c309
tag:         tip
user:        mneedham
date:        Fri Nov 13 16:31:02 2009 +1100
summary:     seem to have screwed up the graphs. Not sure how&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I managed to mess up setting up the good and bad revisions a few times – I somehow had the impression that I needed to manually update to the original good and bad revisions which isn't the case.&lt;/p&gt;
&lt;p&gt;The reset command was my friend before I worked out what I was doing wrong:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="text"&gt;hg bisec -r&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It seems like a neat little feature. I'm sure there are lots of other cool things like this in Mercurial so if you know any let me know!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/MarkNeedham/~4/MwDFSKgTEks" height="1" width="1"&gt;&lt;/img&gt;</description>
	<pubDate>Sat, 14 Nov 2009 01:20:13 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/MarkNeedham/~3/MwDFSKgTEks/</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009: Yawn-Proof Your e-Learning without Busting the Bank</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-8648426582225959123</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/Dhi9QbM56nk/devlearn-2009-yawn-proof-your-e.html</link>
	<description>Stephen Walsh and &lt;a href="http://learningvisions.blogspot.com/"&gt;Cammy Bean&lt;/a&gt; from &lt;a href="http://www.kineo.com"&gt;Kineo&lt;/a&gt; put together an interesting session on how you can create engaging elearning without really burning a hole in your pocket. Cammy and Stephen are friends and I really enjoyed their session. They put together some great examples of elearning that were, let's just say quite stunning! There were some great takeaways for attendees and I've summarised that in this blog.&lt;br&gt;&lt;/br&gt;&lt;h3&gt;Key Takeaways&lt;/h3&gt;&lt;ul&gt;&lt;li&gt; Things that bore people: &lt;ul&gt;&lt;li&gt; Navigation;&lt;/li&gt;&lt;li&gt; Text Heavy;&lt;/li&gt;&lt;li&gt; Endless videos; &lt;/li&gt;&lt;li&gt; Talking heads &lt;/li&gt;&lt;li&gt; Cookie cutter approach to design; &lt;/li&gt;&lt;li&gt; Locked navigation; violating basic rights of freedom; &lt;/li&gt;&lt;li&gt; Systems simulation; &lt;/li&gt;&lt;li&gt; Patronising or elementary content; &lt;/li&gt;&lt;li&gt; Monotony and Redundancy;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; How to design rapidly: &lt;ul&gt;&lt;li&gt; &lt;strong&gt;Show, don't tell&lt;/strong&gt;: Get a prototype out as soon as possible; &lt;em&gt;"Get it wrong first time, and iterate from there."&lt;/em&gt;&lt;/li&gt;&lt;li&gt; Get in front of users as soon as you can; &lt;/li&gt;&lt;li&gt; Keep a playlist of ten tracks of design.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Stephen introduced to the audience his &lt;strong&gt;Ten tracks of design&lt;/strong&gt;: &lt;ol&gt;&lt;li&gt; &lt;strong&gt;Hit me with your best shot&lt;/strong&gt;: Use stories that show what can go wrong. Find the killer fact, stat or quote. Learn from your marketing team.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;Give me a Reason&lt;/strong&gt;: Object to learning objectives. Instead of a dozen boring learning objectives, try a lead-in video and show what &lt;em&gt;normally happens&lt;/em&gt; and then point out how this will solve a problem that your learners will face.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;Getting the best stories:&lt;/strong&gt; Get war stories from your best people and get true stories from your newer people. Don't just go to your senior people -- ask people in the trenches, so that way people who go into this training will actually relate to the real situations. Audio interviews over Skype were a great idea Stephen put forward.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;Tear down the wallpaper&lt;/strong&gt;: Use purposeful graphics. Make them earn their place. &lt;em&gt;"Decoration isn't design."&lt;/em&gt;&lt;/li&gt;&lt;li&gt; &lt;strong&gt;This is assessment in the real world&lt;/strong&gt;: Make it tough as hell. Make it open any time. Do it, prove it, move on. &lt;/li&gt;&lt;li&gt; &lt;strong&gt;Make more mistakes&lt;/strong&gt;: Find the mistakes that hurt the most. Simulate them in elearning. Keep them real, play them out. When you're providing feedback provide more than just incorrect/ correct observations, add context about why a choice is appropriate or not.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;A little less conversation, a little more action&lt;/strong&gt;: Simplicity is tough, cut your training to the bone. Watch out for dialogue amongst characters. Keep text to a minimum and tone it down to the absolute key message! &lt;/li&gt;&lt;li&gt; &lt;strong&gt;What more can I do?&lt;/strong&gt;: Think outside the course -- create a learning campaign. Reach out with online support - don't do everything through elearning! Don't get caught up in the technology, think about the problem and the solution. What's are the different ways to spread the word, the simplest way to get learning out, and the most effective way to get them engaged.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;Keeping it real&lt;/strong&gt;: Make the most of media and use audio and video where it counts! Use real people and film them (think of doing it secretly, so people aren't conscious!). When people's identities are at risk use a witness protection style by blurring people's faces out. Video is proven to be the most effective medium for behavioural skills.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;Now what?&lt;/strong&gt;: The end is the beginning. Call to action and then don't let go! Build in ways to sustain performance and link into your LMS and Knowledge Management System to access follow up activities and resources. Leverage communities of interest and people's desire to be altruistic.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-8648426582225959123?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 13 Nov 2009 19:05:24 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/ugJfxauGFV4/devlearn-2009-yawn-proof-your-e.html</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009 - Leo Laporte's keynote on New Media</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-1503794163242167312</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/JimTDJYRln4/devlearn-2009-leo-laportes-keynote-on.html</link>
	<description>Again a great storytelling keynote by &lt;a href="http://leoville.com/"&gt;Leo Laporte&lt;/a&gt;, arguably the czar of &lt;a href="http://en.wikipedia.org/wiki/New_media"&gt;New Media&lt;/a&gt;. Leo touched upon the stories of his life and the shift from advertising driven mass media to content driven new media where he's trying to be the &lt;span style="font-style: italic;"&gt;"CNN for Geeks"&lt;/span&gt;. Great wisdom and since some people liked my mindmap from yesterday, here's another one. Please click on the image for a larger size. As Leo said, &lt;span style="font-style: italic;"&gt;"Its a river of information, dip your foot in whenever its convenient."&lt;/span&gt;&lt;a href="http://dl.dropbox.com/u/478762/New%20Media.png"&gt;&lt;img src="http://dl.dropbox.com/u/478762/New%20Media.png" alt="" border="0" style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; cursor: hand; width: 560px; height: 258px;"&gt;&lt;/img&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-1503794163242167312?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 13 Nov 2009 17:48:13 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/hi4nLyUCI1k/devlearn-2009-leo-laportes-keynote-on.html</feedburner:origLink></item>
<item>
	<title>Patric Fornasier: Lessons Learned (Part 2: Performance Testing and Garbage Collection)</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-34378650.post-2219408039010602664</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/gyyyevauxL0/lessons-learned-part-2-performance.html</link>
	<description>&lt;div style="text-align: justify;"&gt;This is a continuation of &lt;a href="http://patforna.blogspot.com/2009/10/lessons-learned-part-1-remembering.html" target="_blank"&gt;my previous blog post&lt;/a&gt;. The goal is to sum up some lessons that I've learned during the last couple of months while I was involved in performance tuning a large-scale distributed web-app.&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-weight: bold; font-size: 120%;"&gt;Golden Rules&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;div style="text-align: justify;"&gt;Although there are probably many more rules and good advice out there, these are the ones that I remember off the top of my head as being important:&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Change one thing at a time&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;div style="text-align: justify;"&gt;I often found myself very tempted to violate this rule. The problem with breaking it, however, is easily illustrated with an example: Imagine that you make two changes, &lt;span style="font-style: italic;"&gt;c1&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;c2&lt;/span&gt;, at the same time. If &lt;span style="font-style: italic;"&gt;c1&lt;/span&gt; results in a performance improvement of 20% and &lt;span style="font-style: italic;"&gt;c2&lt;/span&gt; in a performance penalty of 30% you'll get an overall performance deterioration of 10%. Consequently, you'll decide not to implement any of the changes, even though &lt;span style="font-style: italic;"&gt;c1&lt;/span&gt; on its own would have resulted in better performance.&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Look at the system as a whole and fix the slowest running part&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;div style="text-align: justify;"&gt;Even if you can make some part of the system thousands of times faster, it will not affect you application performance if the part you changed was not your primary bottleneck. For example, it doesn't make sense to optimise application code if the bottleneck is the result of a slow running database query. I'd even go as far as saying that it is harmful to optimise parts of the systems, when it's not needed. Firstly, it's a waste of time that could be used for tasks that provide more value. Secondly, making performance optimisations often introduces additional complexity at the code level. If you can't justify this extra complexity with a significant performance boost, don't do it. Of course, I'm not advocating against common sense and sound software design principles. For example, I know that making lots of fine-grained RPC calls is a bad idea, so I'll avoid it in the first place.&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Don't optimise prematuerly, i.e. without measuring&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;div style="text-align: justify;"&gt;This one probably goes hand in hand with the rule above. Don't optimise unless you can prove that it will have an effect on overall system performance. Again, this rule is not an excuse for not using sound software design principles.&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-weight: bold; font-size: 120%;"&gt;Performance Testing Cycle&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;div style="text-align: justify;"&gt;Keeping the above rules in mind, we continuously iterated through the following cycle:&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;ol style="text-align: justify;"&gt;&lt;li&gt;Measure performance&lt;/li&gt;&lt;li&gt;Identify single bottleneck (i.e. pick lowest hanging fruit)&lt;/li&gt;&lt;li&gt;Fix single bottleneck&lt;/li&gt;&lt;li&gt;Verify performance has improved&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;Once step 4 is complete, the cycle restarts. Sometimes, we would loop through this cycle several times a day. Other times, one loop would take us several days or even weeks. This process essentially continued until our release target was reached.&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-weight: bold; font-size: 120%;"&gt;Measuring Performance&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;div style="text-align: justify;"&gt;We used &lt;a href="http://jakarta.apache.org/jmeter/" target="_blank"&gt;JMeter&lt;/a&gt; to generate load against the application under test. We set up the tests so that the generated load would increase over time and therefore put the application increasingly under more stress. While running the tests, we measured a number of parameters. The most important ones were throughput, average response time and CPU utilisation.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Looking at charts similar to the ones shown below, we got a fairly good understanding of how much load the application under test could handle.&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;a href="http://1.bp.blogspot.com/_MoEdKdmWnk0/Sv1uOpnLxpI/AAAAAAAAADk/qFckrFO2WI4/s1600-h/Picture+2.png"&gt;&lt;img src="http://1.bp.blogspot.com/_MoEdKdmWnk0/Sv1uOpnLxpI/AAAAAAAAADk/qFckrFO2WI4/s400/Picture+2.png" alt="" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 129px;" border="0" id="BLOGGER_PHOTO_ID_5403596325881890450"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br&gt;&lt;/br&gt;&lt;div style="text-align: justify;"&gt;In the above charts, for example, you can see that, at some point, application throughput reaches a plateau while the average response time per transactions continuous to grow. At this point, the application reached some physical or logical limit that prevented it from doing more work. The challenge, of course, is to find out what those constraints are in order to increase throughput or reduce response times.&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-weight: bold; font-size: 120%;"&gt;Identifying Bottlenecks&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;div style="text-align: justify;"&gt;Bottlenecks created by hardware constraints are normally quite easy to identify. Usually, the symptoms are maximum CPU utilisation, reaching network bandwidth limits, etc. The solution is often to change and restructure application code. Identifying bottlenecks not directly created by hardware constraints is more difficult. Likely causes are slow running external systems, resource starvation, suboptimal configuration settings, etc.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;In the last project, we eliminated the hypothesis that slow running external systems are constraining our system quite early by taking them out of the equation completely and using stub implementations instead. At the same time, this made our performance tests much more robust, reliable and faster.&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-weight: bold; font-size: 120%;"&gt;Fixing Bottlenecks&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;div style="text-align: justify;"&gt;In the first few weeks of our performance tuning initiative, we made quite a lot of progress. There were a large number of easily identifiable bottlenecks which were relatively trivial to fix. These included simple programming errors, unnecessary database calls, unnecessary network calls, slow running SQL queries, no caching where data was easily cacheable, concurrency issues, etc.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;After some time, however, it started to get more difficult to identify bottlenecks. In particular, there has been one case that I think is worth writing about.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Garbage Collection&lt;/span&gt;&lt;br&gt;&lt;/br&gt;We had already spent several weeks trying to identify a bottleneck, which was not obviously caused by hardware constraints. Here are the things we noticed:&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Throughput reached a plateau at point &lt;span style="font-style: italic;"&gt;t&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Response time grew significantly at the same point &lt;span style="font-style: italic;"&gt;t&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Hardware was far from being exhausted. CPU utilisation, for example, was about 60% at point &lt;span style="font-style: italic;"&gt;t&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Although total CPU utilisation was around 60%, one (of eight) cores was maxing out occasionally&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;The last point was indicative that there was probably a CPU-intensive task executing in a single thread, hence single core. One such task that we could think of was garbage collection. We verified this using Perfmon and found that GC was indeed taking up a large amount of processing time (up to 30%).&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;As a result, we did some reading on how .NET GC works. We've learned that, by default, the GC is optimised for standalone apps running on single-core machines (called Workstation GC). On multiprocessor machines, however, there is an additional GC mode available (called &lt;a href="http://msdn.microsoft.com/en-us/library/ms229357.aspx" target="_blank"&gt;Server GC&lt;/a&gt;). The difference between the two is basically that the latter creates a separate GC heap and GC thread for each processor and that collection occurs in parallel. Here's the change we made to our configuration:&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;br&gt;&lt;/br&gt;&amp;lt;configuration&amp;gt;&lt;br&gt;&lt;/br&gt;  &amp;lt;runtime&amp;gt;&lt;br&gt;&lt;/br&gt;    &amp;lt;gcServer enabled="true" /&amp;gt;&lt;br&gt;&lt;/br&gt;  &amp;lt;/runtime&amp;gt;&lt;br&gt;&lt;/br&gt;&amp;lt;/configuration&amp;gt;&lt;br&gt;&lt;/br&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;After making the above configuration change, the throughput of our application increased by almost a factor 3! At the same time, we were again reaching 100% CPU utilisation and average GC time was down to 2-3%.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Of course, this dramatic change meant that we were dealing with a completely new application profile. Consequently, we restarted our iterative cycle described above again from beginning in order to find the next bottleneck.&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-weight: bold; font-size: 120%;"&gt;Conclusion&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;div style="text-align: justify;"&gt;The fundamental prerequisite for doing effective performance tuning is to have a set of repeatable and reliable performance tests. Ideally, these tests are easy to execute, finish in a reasonable amount of time and give you rapid feedback with regards to how the application is performing. Also, you'll need an isolated environment, which allows you to deploy new versions of the application easily and frequently. This gives you a good platform to experiment with changes. Measuring the difference between these changes with respect to the overall application performance then gives you the ability to make informed choices.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img src="https://blogger.googleusercontent.com/tracker/34378650-2219408039010602664?l=patforna.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 13 Nov 2009 15:14:46 +0000</pubDate>
	<author>noreply@blogger.com (Patric Fornasier)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/patforna/~3/hLFZr5vB0cM/lessons-learned-part-2-performance.html</feedburner:origLink></item>
<item>
	<title>Mark Needham: TDD: Combining the when and then steps</title>
	<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=1819</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/Ht98g0TzrIs/</link>
	<description>&lt;p&gt;I've written before about &lt;a href="http://www.markhneedham.com/blog/2009/04/13/tdd-balancing-dryness-and-readability/"&gt;my favoured approach of writing tests in such a way that they have clear 'Given/When/Then' sections&lt;/a&gt; and something which I come across quite frequently is tests where the latter steps have been combined into one method call which takes care of both of these.&lt;/p&gt;
&lt;p&gt;An example of this which I came across recently was roughly like this:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java"&gt;@Test
&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; shouldCalculatePercentageDifferences&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
	verifyPercentage&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;50&lt;/span&gt;, &lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;, &lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
	verifyPercentage&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;, &lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;, &lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
	verifyPercentage&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;, &lt;span style="color: #cc66cc;"&gt;50&lt;/span&gt;, &lt;span style="color: #cc66cc;"&gt;-50&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;


&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; verifyPercentage&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;int&lt;/span&gt; originalValue, &lt;span style="color: #000066; font-weight: bold;"&gt;int&lt;/span&gt; newValue, &lt;span style="color: #000066; font-weight: bold;"&gt;int&lt;/span&gt; expectedValue&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
	assertEquals&lt;span style="color: #009900;"&gt;(&lt;/span&gt;expectedValue, &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; PercentageCalculator&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;calculatePercentage&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;originalValue, newValue&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This code is certainly adhering to the DRY principle although it took us quite a while to work out what the different numbers being passed into 'verifyPercentage' were supposed to represent.&lt;/p&gt;
&lt;p&gt;With this type of test I think it makes more sense to have a bit of duplication to make it easier for us to understand the test.&lt;/p&gt;
&lt;p&gt;We changed this test to have its assertions inline and make use of the &lt;a href="http://code.google.com/p/hamcrest/"&gt;Hamcrest&lt;/a&gt; library to do those assertions:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java"&gt;@Test
&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; shouldCalculatePercentageDifferences&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
	assertThat&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; PercentageCalculator&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;calculatePercentage&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;50&lt;/span&gt;, &lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;, is&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
	assertThat&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; PercentageCalculator&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;calculatePercentage&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;, &lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;, is&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
	assertThat&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; PercentageCalculator&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;calculatePercentage&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;, &lt;span style="color: #cc66cc;"&gt;50&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;, is&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;-50&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I think we may have also created a field to instantiate 'PercentageCalculator' so that we didn't have to instantiate that three times.&lt;/p&gt;
&lt;p&gt;Although we end up writing more code than in the first example I don't think it's a problem because it's now easier to understand and we'll be able to resolve any failures more quickly than we were able to previously.&lt;/p&gt;
&lt;p&gt;As Michael Feathers points out during Jay Fields' '&lt;a href="http://blog.jayfields.com/2009/06/developer-testing-welcome-to-beta-test.html"&gt;Beta Test&lt;/a&gt;' presentation we need to remember why we try and adhere to the &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY principle&lt;/a&gt; in the first place.&lt;/p&gt;
&lt;p&gt;To paraphrase his comments:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
In production code if we don't adhere to the DRY principle then we might make a change to a piece of code and we won't know if there's another place where we need to make a change as well.&lt;/p&gt;
&lt;p&gt;In test code the tests always tell us where we need to make changes because the tests will break.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;img src="http://feeds.feedburner.com/~r/MarkNeedham/~4/dDnrYedsQlQ" height="1" width="1"&gt;&lt;/img&gt;</description>
	<pubDate>Fri, 13 Nov 2009 14:17:57 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/MarkNeedham/~3/dDnrYedsQlQ/</feedburner:origLink></item>
<item>
	<title>Jie Xiong: 三人成众</title>
	<guid isPermaLink="false">tag:gigix.thoughtworkers.org,2009-11-13:648</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/nDQDHGNPwdU/magic-of-3-people-team</link>
	<description>&lt;p&gt;一个人是孤单的，就像“人”字，只能自己支撑自己。&lt;/p&gt;


	&lt;p&gt;两个人的团队，如果不是互相对立的话，就难免有一人比较强势。如同一个“从”字，主从关系往往确定下来就不易改变。&lt;/p&gt;


	&lt;p&gt;四个人或更多人的团队，就常会分裂成小帮派。&lt;/p&gt;


	&lt;p&gt;三个人的团队是个绝配。三人成“众”，既互相支撑，又互相平衡，均势来回变，难有某一人永远强势。一起出现，三人不显太多；分开行动，一人两人可以灵活配置。&lt;/p&gt;


	&lt;p&gt;而且争吵能得到有效控制。一旦两人出现争执，另一人便可客观评判，居中调停。而且这次的旁观者下次就可能成了争执的一方，这次的争执者下次又换了调停的角色。于是每个人在身涉争执时大可各执一端畅所欲言，因为信任旁观者已有准备平息战火。于是争执也常被带往健康的方向。&lt;/p&gt;


	&lt;p&gt;所以如果去陌生而紧张的环境工作，三个人的团队是很好的选择。&lt;/p&gt;</description>
	<pubDate>Fri, 13 Nov 2009 11:20:47 +0000</pubDate>
<feedburner:origLink>http://gigix.thoughtworkers.org/2009/11/13/magic-of-3-people-team</feedburner:origLink></item>
<item>
	<title>Patric Fornasier: RSpec and TextMate</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-34378650.post-5423073339393887407</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/JcGp0BT2CmI/rspec-and-textmate.html</link>
	<description>Just struggled to get the &lt;a href="http://rspec.info/" target="_blank"&gt;RSpec&lt;/a&gt; bundle working with &lt;a href="http://macromates.com/" target="_blank"&gt;TextMate&lt;/a&gt;. After installing the bundle as described on the &lt;a href="http://rspec.info/documentation/tools/extensions/editors/textmate.html" target="_blank"&gt;RSpec site&lt;/a&gt;, I kept getting the following error message:&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;Library/Application Support/TextMate/Bundles/RSpec.tmbundle/Support/lib/spec/mate.rb:4:in `join': can't convert nil into String (TypeError)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;After a few hours of fruitless searching on the web, it occured to me that I should maybe have a look at the file listed in the error message above (&lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;mate.rb:4&lt;/span&gt;&lt;/span&gt;).&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;File.join(ENV['TM_PROJECT_DIRECTORY'],'vendor','plugins','rspec','lib')&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;The bundle basically failed, because the &lt;span&gt;TM_PROJECT_DIRECTORY&lt;/span&gt; variable was not set.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;So, instead of trying to run the file in standalone mode, I pulled the spec file into a new project (⌃⌘N) and ran it again.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Et voilà. No errors this time round. ...and thanks so much for the helpful error message, RSpec-TextMate-bundle! *grrr*&lt;div class="blogger-post-footer"&gt;&lt;img src="https://blogger.googleusercontent.com/tracker/34378650-5423073339393887407?l=patforna.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 13 Nov 2009 11:09:40 +0000</pubDate>
	<author>noreply@blogger.com (Patric Fornasier)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/patforna/~3/0gieR7ChCvA/rspec-and-textmate.html</feedburner:origLink></item>
<item>
	<title>Simon Brunning: Links for 2009-11-12 [del.icio.us]</title>
	<guid isPermaLink="false">http://del.icio.us/brunns#2009-11-12</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/RGem3oNtmKc/brunns</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blog.extracheese.org/2009/11/the_limits_of_tdd.html"&gt;The Limits of TDD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://playthisthing.com/doom-roguelike"&gt;Doom, The Roguelike&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.guardian.co.uk/global/video/2009/nov/10/charlie-brooker-hyde"&gt;Marina Hyde's interview with Charlie Brooker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/rzaie/rzaieprognetdata.htm"&gt;Net.Data programs for the HTTP Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jacobian.org/writing/great-documentation/what-to-write/"&gt;Writing great documentation: what to write&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
And Jacob knows whereof he speaks; the Django documentation is exemplary.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.thekua.com/atwork/2009/11/what-they-dont-tell-you-about-user-stories/"&gt;What they don’t tell you about user stories&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jacobian.org/writing/great-documentation/technical-style/"&gt;Writing great documentation: technical style&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.as400network.com/index400/"&gt;iSeries DocFinder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www-03.ibm.com/systems/i/"&gt;IBM i For Power Systems including AS/400, iSeries, and System i&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.penny-arcade.com/comic/2009/10/30/"&gt;In The Seventh House&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://scienceblogs.com/goodmath/2009/11/googles_new_language_go.php"&gt;Google's New Language: Go&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Lots of detail here.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.googlewaveinfo.com/200911/google-wave-cheat-sheet/?utm_source=twitterfeed"&gt;Google Wave Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Fri, 13 Nov 2009 08:00:00 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/SmallValuesOfCool/~3/yVmmPf2-2_M/brunns</feedburner:origLink></item>
<item>
	<title>Felix Leipold: Using Extension Methods</title>
	<guid isPermaLink="false">http://wuetender-junger-mann.de/wordpress/?p=877</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/vwOme7wrr98/</link>
	<description>&lt;p&gt;
I came up with the following extensions method in C#:
&lt;/p&gt;&lt;p&gt;
&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre&gt; 
&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;static&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;class&lt;/span&gt; NeatExtensions&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
    &lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;static&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;bool&lt;/span&gt; In&amp;lt;T&amp;gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0600FF;"&gt;this&lt;/span&gt; T element, &lt;span style="color: #0600FF;"&gt;params&lt;/span&gt; T&lt;span style="color: #000000;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;]&lt;/span&gt; elements&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
        &lt;span style="color: #0600FF;"&gt;return&lt;/span&gt; &lt;a href="http://www.google.com/search?q=new+msdn.microsoft.com"&gt;&lt;span style="color: #008000;"&gt;new&lt;/span&gt;&lt;/a&gt; HashSet&amp;lt;T&amp;gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;elements&lt;span style="color: #000000;"&gt;)&lt;/span&gt;.&lt;span style="color: #0000FF;"&gt;Contains&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;element&lt;span style="color: #000000;"&gt;)&lt;/span&gt;;
    &lt;span style="color: #000000;"&gt;}&lt;/span&gt;
&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
It actually yields a nice syntax for checking enum values and the likes:
&lt;/p&gt;
&lt;code&gt;&lt;pre&gt; 
enumValue.&lt;span style="color: #0000FF;"&gt;In&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Enum&lt;/span&gt;.&lt;span style="color: #0000FF;"&gt;X&lt;/span&gt;, &lt;span style="color: #FF0000;"&gt;Enum&lt;/span&gt;.&lt;span style="color: #0000FF;"&gt;Z&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;
I am wondering whether there is actually a de-factor standard library in the C# world that has extensions like this.</description>
	<pubDate>Fri, 13 Nov 2009 00:06:46 +0000</pubDate>
<feedburner:origLink>http://wuetender-junger-mann.de/wordpress/?p=877</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009 - Web 2.0 and Performance: What's working for Google employees</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-1121633980985076213</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/jdQlhemG2dM/devlearn-2009-web-20-and-performance.html</link>
	<description>The last session I attended today was by Julia Bulkowski and Erika Grouell from Google about how they're leveraging Web 2.0 technologies to help drive performance in their company. Again, nothing new given that Google's products are all free for public use. This said, it was a great reinforcement of how much you can do with just one integrated (single sign-on suite).&lt;br&gt;&lt;/br&gt;&lt;h3&gt;Key Takeaways&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Culture is key&lt;/span&gt; to adoption of Web 2.0 technologies.Google and &lt;a href="http://www.thoughtworks.com"&gt;ThoughtWorks&lt;/a&gt; have very unique cultures that are geared towards rapid technology adoption, minimal access barriers and hierarchy and a lot of companies still need to figure out the best structure to make Enterprise 2.0 adoption succeed.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt; A clever use of blogs and discussion forums:&lt;/span&gt; Practicing and reviewing transactional skills like writing and email communication.&lt;/li&gt;&lt;li&gt; &lt;span style="font-weight: bold;"&gt;A clever use of &lt;a href="http://code.google.com/labs/"&gt;Google Code Labs&lt;/a&gt;&lt;/span&gt;: Leverage fellow software developers to learn a programming language. Use Google Code labs to provide code snippets to learn practical styles and patterns of programming. Very wiki like, especially with revision history and crowdsourced descriptions. This makes experts visible and lets new developers ramp-up quicker.&lt;/li&gt;&lt;li&gt; A &lt;span style="font-weight: bold;"&gt;clever way of sharing instructional resources&lt;/span&gt;: Create a &lt;a href="http://wave.google.com"&gt;Google Wave&lt;/a&gt; and embed it into your class homepage. People can discuss the problem amongst themselves, but at the same time make a private submission to the instructor if this was an assignment, test, etc.&lt;/li&gt;&lt;li&gt; &lt;span style="font-weight: bold;"&gt;A clever use of online photo and video sharing:&lt;/span&gt; Sharing howto's, tips, screencasts, tutorials. Take a look at YouTube's &lt;a href="http://www.youtube.com/user/GoogleApps"&gt;Google Apps Channel&lt;/a&gt;. As a social tool as well, users can create their own tutorials, etc and they could do videos of themselves doing presentations and get feedback from each other.&lt;/li&gt;&lt;li&gt; &lt;span style="font-weight: bold;"&gt;Clever way of preparing for a session, panel discussion, conference talk:&lt;/span&gt; Use &lt;a href="http://moderator.appspot.com/"&gt;Google Moderator&lt;/a&gt; so participants can brainstorm questions for the session. Helps you prepare as a speaker as well.&lt;/li&gt;&lt;li&gt; Providing Web 2.0 services in the enterprise is a way of reducing your risk. If you don't, people will in any case use these tools outside and then you don't have any control and have in a way increased your own risk!&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-1121633980985076213?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 13 Nov 2009 00:06:20 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/RT-M5Oun66M/devlearn-2009-web-20-and-performance.html</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009: Catch the WAVE: Google WAVE and e-Learning Applications</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-7879205601515557970</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/Na1r50Etxyk/devlearn-2009-catch-wave-google-wave.html</link>
	<description>This afternoon I sat through Adam Mash's (? I think that's his name) session on &lt;a href="http://wave.google.com"&gt;Google Wave&lt;/a&gt;. Being a Google Wave tester, nothing that he said was new for me except he highlighted a few things worth reiterating.&lt;br&gt;&lt;/br&gt;&lt;h3&gt;So what should you know about Google Wave&lt;/h3&gt;There are some really interesting uses for Google Wave:&lt;ul&gt;&lt;li&gt;Collaborative creation of documents, reports, observations, requests&lt;/li&gt;&lt;li&gt;Group/ Afilliation rosters;&lt;/li&gt;&lt;li&gt; Agenda, meeting minutes, to-do list combos; &lt;/li&gt;&lt;li&gt; Collaborative proposal Writing and approval; &lt;/li&gt;&lt;li&gt; Collective visioning and brainstorming; &lt;/li&gt;&lt;li&gt; Getting to know you style stuff &lt;/li&gt;&lt;li&gt; Fun, special interest conversations&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;A few things that people may not know about Wave&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://completewaveguide.com/"&gt;The complete wave guide&lt;/a&gt; -- all there is to know about Wave&lt;/li&gt;&lt;li&gt; You can &lt;a href="http://www.steitblog.com/2009/11/04/how-to-create-a-public-wave-in-google-wave/"&gt;create&lt;/a&gt; and &lt;a href="http://www.dablogmother.com/2009/10/google-wave-find-public-waves.html"&gt;access public waves&lt;/a&gt;. You can explictly choose to &lt;a href="http://www.google.com/support/forum/p/wave/thread?tid=6274cda9fd20fd67&amp;amp;hl=en"&gt;follow public waves&lt;/a&gt;.&lt;/li&gt;&lt;li&gt; Wave is an open protocol, so it is possible to create custom clients to interact with Wave. &lt;/li&gt;&lt;li&gt; Just like every other Google Application, Wave is extensible and there are already quite a few extensions in play for Google Wave, that will make it a fully featured collaboration platform whenever it is out. &lt;/li&gt;&lt;li&gt; It is not possible to remove people from a wave, yet. &lt;/li&gt;&lt;li&gt; Support for mailing lists and groups isn't great yet. Actually its almost non-existent.&lt;/li&gt;&lt;li&gt; There's a twitter feed for google wave at &lt;a href="http://twitter.com/search?q=%23googlewave"&gt;#googlewave&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-7879205601515557970?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 12 Nov 2009 22:58:12 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/2k_bvJTUZtQ/devlearn-2009-catch-wave-google-wave.html</feedburner:origLink></item>
<item>
	<title>Mark Needham: Adapting our approach for the context</title>
	<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=1816</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/RGTGEAZltHw/</link>
	<description>&lt;p&gt;Amongst the many posts written recently about unit testing one which I quite liked was &lt;a href="http://fallenrogue.com/post/234250827/re-its-ok-not-to-unit-test-or-what-you-do-on-your"&gt;written by fallenrogue&lt;/a&gt; where he describes how in different contexts/cultures a different approach is favoured which means a technique like TDD might not work so well.&lt;/p&gt;
&lt;p&gt;cashto, the guy who wrote &lt;a href="http://blogs.msdn.com/cashto/archive/2009/03/31/it-s-ok-not-to-write-unit-tests.aspx"&gt;the original post&lt;/a&gt;, agrees with this in the comments on that post:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
Absolutely right. I write apps on mobile devices in C++. What works for me may not work well for someone who designs websites with RoR, and vice versa. Context definitely matters — it was one of the points I was trying to get across.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Recently I've started noticing that it's quite beneficial to &lt;a href="http://www.markhneedham.com/blog/2009/10/05/my-software-development-journey-year-3-4/"&gt;consider the context&lt;/a&gt; that we're working in for all sorts of approaches we might want to take.&lt;/p&gt;
&lt;h3&gt;Immutability&lt;/h3&gt;
&lt;p&gt;When I was first playing around with &lt;a href="http://www.markhneedham.com/blog/category/dotnet/f-dotnet/"&gt;F#&lt;/a&gt; I liked the idea of having everything in the code being immutable and I decided that it would be interesting to try and apply that idea to the code I wrote in C# on the project I was working on.&lt;/p&gt;
&lt;p&gt;Unfortunately it didn't work out as well as I'd hoped because it requires more code to do that, it's not really idiomatic C# so it was confusing to my colleagues and we ended up having objects hanging around which weren't updated with the latest state changes because I'd forgotten to re-assign the variable to the new instance.&lt;/p&gt;
&lt;p&gt;I still think that we could probably make more use of &lt;a href="http://www.markhneedham.com/blog/2009/03/15/qcon-london-2009-the-power-of-value-power-use-of-value-objects-in-domain-driven-design-dan-bergh-johnsson/"&gt;value objects&lt;/a&gt; in our code but I'm not convinced that aiming for immutability everywhere when using C# is the way to go.&lt;/p&gt;
&lt;p&gt;If it was a different context such as a problem we were trying to solve in Haskell or to a lesser extent F# then it would make perfect sense.&lt;/p&gt;
&lt;h3&gt;Confidence changing code&lt;/h3&gt;
&lt;p&gt;Another example of this is the confidence that we can have in making changes to the code base.&lt;/p&gt;
&lt;p&gt;I've worked on projects where there's been a lot of test coverage across the board and also ones where there wasn't.&lt;/p&gt;
&lt;p&gt;With the latter we'd have to put some time in to get tests around that code before thinking about making big changes.&lt;/p&gt;
&lt;p&gt;If we don't have the time to do that then we need to be quite careful when changing code since we don't have a quick feedback mechanism to let us know whether we've broken anything or not.&lt;/p&gt;
&lt;h3&gt;Final thoughts&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://programmingtour.blogspot.com/2009/10/on-term-pragmatic.html"&gt;Corey Haines wrote a post on pragmatism&lt;/a&gt; about a month ago where he suggested the following:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
Often times, people use the term 'pragmatic' as a way to hide a lack of skill and experience. Or, sometimes, it is used in ignorance: someone doesn't realize that they don't understand something well enough. Usually, though, it is brought to play when someone is justifying cutting corners on something.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I think this applies when deciding that an approach isn't useful in our context. We need to be careful that we're not just making excuses for our lack of skill in that area.&lt;/p&gt;
&lt;p&gt;When I first started working professionally in software development I was fairly convinced that there would be an optimal approach to take in every situation that I just didn't know about yet.&lt;/p&gt;
&lt;p&gt;A few years later I've come across a lot of really good approaches to solving problems but no approach that is applicable across the board.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/MarkNeedham/~4/rxLwM9rV00Q" height="1" width="1"&gt;&lt;/img&gt;</description>
	<pubDate>Thu, 12 Nov 2009 20:34:00 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/MarkNeedham/~3/rxLwM9rV00Q/</feedburner:origLink></item>
<item>
	<title>Dan North: The lady in the taxi – a parable of metrics</title>
	<guid isPermaLink="false">http://dannorth.net/?p=173</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/c00wj7grt0c/the-lady-in-the-taxi-a-parable-of-metrics</link>
	<description>&lt;p&gt;&lt;/p&gt;&lt;p id="top"&gt;Once upon a time there was a lady in a taxi. It took such a long time for the lady to get to her destination in the taxi that she went to the town hall and told the man from the council.  The man from the council wanted to figure out why the taxi journey was so slow, so he placed cameras at all the traffic lights in the town to measure how many cars went past, and how quickly. The traffic light cameras would &lt;em&gt;click&lt;/em&gt; every time a car went past the lights.&lt;/p&gt;
	&lt;p&gt;He wanted to speed up the rate of cars, so he changed the layout of the town.  He figured if he introduced a one-way system the traffic flow would be more efficient. This confused the taxi drivers and they started to get lost. The taxi driver would go past a light, &lt;em&gt;click&lt;/em&gt;, discover he couldn’t go the way he wanted, try to find a way through and find himself going back past the same light, &lt;em&gt;click&lt;/em&gt;, realise he had been this way before, turned around and drive back through the light, &lt;em&gt;click&lt;/em&gt;, and would still not find his way to the lady’s destination. The new one-way system was good at moving cars around – it just wasn’t very easy to navigate. And just as the taxi drivers were learning the new layout, the man from the council would try a new layout just in case.&lt;/p&gt;
	&lt;p&gt;What a lot of clicking, thought the man from the council, and what a lot of cars must be driving through my town. How efficient this is! I shall invite more cars into this town because it is so efficient at moving cars around.&lt;/p&gt;
	&lt;p&gt;So he invited more cars into the town, which of course just clogged up the streets. Every time the light would go green, a line of cars, nose-to-tail, would crawl through the lights: &lt;em&gt;click&lt;/em&gt;, &lt;em&gt;click&lt;/em&gt;, &lt;em&gt;click&lt;/em&gt;! When they were past the lights, they would sit stuck in traffic. Sometimes the taxi drivers would get so fed up they would just abandon the journey and make the lady get out of the taxi. Of course she would have to pay for the journey so far. And wait for another taxi. And get in and try to resume the journey. (She often had to go a way back up the road to find another taxi.) Same lady, same journey, different taxi, back through the same lights. &lt;em&gt;Click&lt;/em&gt;, &lt;em&gt;click&lt;/em&gt;.&lt;/p&gt;
	&lt;p&gt;The taxi drivers realised they were losing money by spending all day in traffic jams, so they decided to have two kinds of tariff. When the taxi was moving they would charge by the mile.  When the taxi was stopped, they would charge for waiting.  What a clever idea!&lt;/p&gt;
	&lt;p&gt;This made the lady very upset. It is taking me longer than ever to get to my destination, she thought, and it is getting more and more expensive because it is costing me money just to sit here.&lt;/p&gt;
	&lt;p&gt;She sighed and looked out of the taxi window, and saw the cameras at the traffic lights.  Then she realised what was happening. The poor man from the council thought that each time the same taxi went past the light, it was a &lt;em&gt;different vehicle&lt;/em&gt;! He thought that when different taxis were taking the same lady to the same destination, that it was &lt;em&gt;different jouneys&lt;/em&gt;! He probably figured that having lots of cars going through the lights meant they were travelling quickly!&lt;/p&gt;
	&lt;p&gt;Then she had an idea. I shall take a camera &lt;em&gt;in the taxi&lt;/em&gt; she thought, and I shall show the film to the man from the council. So she took a camera in the taxi (and cleverly recorded the taxi meter at the same time).  Look at this, she said to the man from the council. Ths shows you my experience as a passenger in the taxi. I move from red traffic light to red traffic light, crawling through the lights in a little batch of cars, queued up behind the next traffic light.  I don’t mind paying for the mileage, but I don’t think I should have to pay just to sit waiting to go forwards. And to make matters worse, the journey to my destination is taking longer and longer!&lt;/p&gt;
	&lt;p&gt;Oh my! said the man from the council. I’ve been looking at the wrong thing all along. Instead of trying to maximise the amount of cars that go through a particular light, I should try to minimise the amount of time it takes you to get to your destination! How silly of me.&lt;/p&gt;
	&lt;p&gt;Oh, and perhaps &lt;em&gt;I&lt;/em&gt; should pay &lt;em&gt;you&lt;/em&gt; if you have to sit there in a taxi because my town is all backed up with traffic. At least then there would be an incentive for me to work on the most blocked-up parts of the town. Perhaps they are the &lt;em&gt;only&lt;/em&gt; places I should be concerned with anyway, because by unblocking the most constrained parts I will probably have a better flow of traffic altogether. And perhaps when a particular street is backed up, I should stop more traffic coming in and causing traffic jams.&lt;/p&gt;
	&lt;p&gt;Thank you! said the lady. I now feel like you really are going to be able to help me to get to my destination quicker. I know it won’t happen overnight, but I am sure that over time my journeys will be faster. That’s quite alright, said the man from the council. Thanks for teaching me to look from the point of view of a passenger in the taxi, and not just to take snapshots from the different stages of the journey.&lt;/p&gt;
	&lt;p&gt;And they all lived happily ever after.&lt;/p&gt;
	&lt;p&gt;&lt;em&gt;Thanks to &lt;a href="http://sustorevilo.blogspot.com/"&gt;Oliver Schreck&lt;/a&gt; for the idea that led to this story.&lt;/em&gt;&lt;/p&gt;</description>
	<pubDate>Thu, 12 Nov 2009 20:15:51 +0000</pubDate>
<feedburner:origLink>http://dannorth.net/2009/11/the-lady-in-the-taxi-a-parable-of-metrics</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009 - Eric Zimmerman's Keynote on "Meaningful Play"</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-2600557660307611717</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/ylXIiFJIFTY/devlearn-2009-eric-zimmermans-keynote.html</link>
	<description>I can't attempt to summarise Eric's keynote, also because I feel woefully inadequate to be able to tie together the thousand pieces of wisdom and interconnections that he through out in the speech. My slow brain's going to take some time to process this information. But anyways, I did a mindmap while Eric was presenting, and I'd like to share it with you. Here you go! Click on the mindmap for a full-size version, because I imagine it'll be impossible to read at this size. Again, its a very personal note-taking approach, so I don't imagine it'll be most intuitive.&lt;br&gt;&lt;/br&gt;&lt;a href="http://dl.dropbox.com/u/478762/Serious%20Games.png"&gt;&lt;img src="http://dl.dropbox.com/u/478762/Serious%20Games.png" alt="" border="0" style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; cursor: hand; width: 560px; height: 364px;"&gt;&lt;/img&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-2600557660307611717?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 12 Nov 2009 18:19:23 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/U_WIXHakhmc/devlearn-2009-eric-zimmermans-keynote.html</feedburner:origLink></item>
<item>
	<title>Paulo Caroli: Most if-statements are evil</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-9212598583517336757.post-7807365806251845907</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/tTsr3pPpX-0/most-if-statements-are-evil.html</link>
	<description>&lt;div style="text-align: left;"&gt;I’ve really come to loath if-statements. It developed over time. At the very beginning they are great as they give you the power to put some logic into you application. Usually a small program in one of your first programming classes. Well, over time I realized the hard way that they clutter your code and make it harder to read and hence understand and maintain. In OO languages you have far more powerful ways to put logic into your application without using if’s. However, this requires a good skill in programming and lots of practice. I’ve come to realize that you can identify a good programmer by her if-avoidance skill. Well, after some time in acceptance but dislike I now try to avoid them at any price and so should you. By the way, I consider switch-statements to be nested if’s.&lt;/div&gt;&lt;br&gt;&lt;/br&gt;Frederick Brooks coined once the terms ‘Essential Complexity’ and ‘Accidental Complexity’. The first describes the real complexity which comes from the domain and the problem to solve. The second one is manmade i.e. it is the complexity we get into by our own making like which OS, which language, which framework, … we choose. Using this point of view, there are essential if-statements and accidental if-statements. The accidental ones, what a fitting name, are the ones which need to be eliminated.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;b&gt;Essential if’s&lt;/b&gt;&lt;br&gt;&lt;/br&gt;There are things you need to check. Can I save the file, is there enough free disk space.&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;if (diskHasEngoughFreeSpace()) {&lt;br&gt;&lt;/br&gt;document.save();&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;Those decision are driven from external forces and are out of our control and so we need to check them every time we save.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;b&gt;Accidental if’s&lt;/b&gt;&lt;br&gt;&lt;/br&gt;Those buggers creep up everywhere in you code.&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;if (date == null) {&lt;br&gt;&lt;/br&gt;date = new Date(); // this is called defensive programming, one of the worst things you can do&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;or&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;if (date != null) {&lt;br&gt;&lt;/br&gt;uiWidget.setText(date.toString());&lt;br&gt;&lt;/br&gt;} else {&lt;br&gt;&lt;/br&gt;uiWidget.setText(“”);&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;Before you get creative in finding a workaround you should analyze whether date actually can be null. If yes, how? Is it a field of the class, a parameter of the method, a return value from a called method. All these questions and their answers provide you with a multitude of options.&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;/**&lt;br&gt;&lt;/br&gt;* @param date of the document to be printed; must not be null&lt;br&gt;&lt;/br&gt;*/&lt;br&gt;&lt;/br&gt;public void printHeader(Date date) {&lt;br&gt;&lt;/br&gt;// Usually I put those checks into a utility class and a checkParam method.&lt;br&gt;&lt;/br&gt;// i.e. Check.checkNotNull(date, “date”);&lt;br&gt;&lt;/br&gt;if (date == null) throw new IllegalArgumentException(“invalid parameter: date cannot be null. Good bye!”);&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;// once we are here we know that all parameter are valid&lt;br&gt;&lt;/br&gt;date.doSomething();&lt;br&gt;&lt;/br&gt;…&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;It is a good practice to have an object to be in well pre-defined state after creation.&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;class DocumentPrinter {&lt;br&gt;&lt;/br&gt;private Date date; // this is the same as private Date date = null;&lt;br&gt;&lt;/br&gt;…&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;It is better to do it this way&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;class DocumentPrinter {&lt;br&gt;&lt;/br&gt;private Date date = Date();&lt;br&gt;&lt;/br&gt;// if this is not sufficient then have  the date passed in as parameter with the constructor and make the default constructor private&lt;br&gt;&lt;/br&gt;…&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;or even better use the Null-Object pattern&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;class Document Printer {&lt;br&gt;&lt;/br&gt;private Date date = new NullDate();&lt;br&gt;&lt;/br&gt;…&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;class NullDate extends Date {&lt;br&gt;&lt;/br&gt;public void toString() {&lt;br&gt;&lt;/br&gt;return “not set”;&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;From now on you can use date anywhere in your class without the need to check for null.&lt;br&gt;&lt;/br&gt;Now lets look at a return value from a called method. First I would study the documentation of the method and see whether the method actually can return null objects. In important cases I would even go so far as to quickly write a bunch of tests. With those tests you have clear documentation if the method can return null and under which conditions.&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;public void doSometing() {&lt;br&gt;&lt;/br&gt;…&lt;br&gt;&lt;/br&gt;Date date = getDateOfTransaction(transaction);&lt;br&gt;&lt;/br&gt;…&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;Knowing, that date might be null we need to see how the variable is being used subsequently. If it is being used for some simple display purposes we can wrap the method and return a NullDate in case the return value is null. If there is some more serious work with the object down the road then ‘Houston we have a problem’! Creating a fake date will not work and invite some big risks. Bypassing the date accesses even more so:&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;…&lt;br&gt;&lt;/br&gt;doThis();&lt;br&gt;&lt;/br&gt;doThat();&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;if (date != null) {&lt;br&gt;&lt;/br&gt;rebate = calculateRebate(date);&lt;br&gt;&lt;/br&gt;bookTransaction(rebate);&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;…&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;Sure, we could move the bookTransaction-method out of the block and guarantee that it will be always booked. But, assuming that we are dealing with a preferred customer who always gets a 10% discount. In this case we will get bunch of calls to our customer service folks which would have to deal with an upset customer. We don’t want that. Depending on whether you have access to the source code of used method you can go in fix the problem if not then you have a problem which you should encapsulate. The encapsulated problem offers a clear separation between working and broken smelly workaround code. Also it adds a lot the readability of the source code and you would have only one place to go and do the fix.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;But now let’s look at another piece of code. Assuming we have so transmit data via a selectable protocol. The transmission must be encrypted under specific circumstances. So the code could look like this&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;public void send(String text, String transmission, String encryption) {&lt;br&gt;&lt;/br&gt;String sendText = “”;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;if (encryption.equals(“RSA128”)) {&lt;br&gt;&lt;/br&gt;encryption = new RSA128();&lt;br&gt;&lt;/br&gt;sendText = encryption.encrypt(text);&lt;br&gt;&lt;/br&gt;} else if (encryption.equals(“RSA1024”)) {&lt;br&gt;&lt;/br&gt;encryption = new RSA128();&lt;br&gt;&lt;/br&gt;sendText = encryption.encrypt(text);&lt;br&gt;&lt;/br&gt;} else { // no encryption&lt;br&gt;&lt;/br&gt;sendText = text;&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;if (transimission.equals(“ftp”)) {&lt;br&gt;&lt;/br&gt;FTPTransmitter transmitter = new FTPTransmitter();&lt;br&gt;&lt;/br&gt;transmitter.transmit(sendText);&lt;br&gt;&lt;/br&gt;} else if (transmission.equals(“ssh”)) {&lt;br&gt;&lt;/br&gt;SSHTransmitter transmitter = new SSHTransmitter();&lt;br&gt;&lt;/br&gt;transmitter.transmit(sendText);&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;How about this&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;public void send(String text, String transmission, String encryption) {&lt;br&gt;&lt;/br&gt;Transmitter transmitter = Factory.createTransmitter(transmission, encryption);&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Transmitter.transmit(text);&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://3.bp.blogspot.com/_PM2cUrnA_54/Svv0CrZTpmI/AAAAAAAAADA/OpPIP6kEyEs/s400/TransmitterEncryptionStrategy.JPG"&gt;&lt;/img&gt;&lt;div&gt;&lt;br&gt;&lt;/br&gt;First, we extracted a Transmitter interface or if feasible an abstract class. The transmitter internally uses a strategy pattern to encrypt the text. The encryption is injected during construction time of the Transmitter. Again, there is an abstraction for the encryption. The factory could be a own creation or you could use a framework like Spring.&lt;br&gt;&lt;/br&gt;&lt;pre&gt;&lt;code&gt;&lt;br&gt;&lt;/br&gt;class Factory {&lt;br&gt;&lt;/br&gt;public static Transmitter createTransmitter(String transmission, String encryption) {&lt;br&gt;&lt;/br&gt;Encryption encryptionObj = createEncryption(encryption);&lt;br&gt;&lt;/br&gt;return createTransmitter(transmission, encryptionObbj);&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;public static Transmitter createTransmitter(String transmission, Encryption encryption) {&lt;br&gt;&lt;/br&gt;Transmitter transmitter = createTransmitter(transmission);&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;transmitter.setEncryption(encryption);&lt;br&gt;&lt;/br&gt;return transmitter;&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;…&lt;br&gt;&lt;/br&gt;}&lt;br&gt;&lt;/br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/br&gt;Sure, if you were following correctly I would expect a ‘but now we have the if-statements in the conveniently not shown createEnryption and createTransmitter method’. Yes, your are right. However, I consider those if-statements at this location to be essential. Also, if you use Spring the condition checking will be externalized into the bean descriptor file.&lt;br&gt;&lt;/br&gt;Also, since the factory is driven by Strings, these could easily come from the UI. In that regard the UI would drive the behaviour without adding any conditional checking and would be easily extendable to other means of transmission and encryption without the need to modify it. And yes, the code will much easier to test. MockObjects anyone ;)&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/br&gt;&lt;/div&gt;&lt;div&gt;PS &lt;i&gt;If anyone can give a me hint to how show source code in a nice and readable using Blogger. This would be highly appreciated.&lt;/i&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img src="https://blogger.googleusercontent.com/tracker/9212598583517336757-7807365806251845907?l=agiletips.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 12 Nov 2009 12:04:21 +0000</pubDate>
	<author>noreply@blogger.com (Ralph Jocham)</author>
<feedburner:origLink>http://agiletips.blogspot.com/2009/06/most-if-statements-are-evil.html</feedburner:origLink></item>
<item>
	<title>Ola Bini: QCon San Francisco, RubyConf and JRubyConf</title>
	<guid isPermaLink="false">http://olabini.com/blog/?p=686</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/mk7YBQjCctk/</link>
	<description>&lt;p&gt;I’m gearing up for the next conference stretch. This time it’s San Francisco next week, and I really hope to see lots of people at these conferences - they are gearing up to be something special.&lt;/p&gt;
&lt;p&gt;First QCon San Francisco. Except for JAOO, QCon is the best general developer conference I’ve ever been to. Go check out the schedule at &lt;a href="http://qconsf.com"&gt;http://qconsf.com&lt;/a&gt;. This year I’m very excited about doing a full day tutorial about domain specific languages together with Martin Fowler.&lt;/p&gt;
&lt;p&gt;I’m also in charge of the languages track, where I have five people who will talk about their experiences with different languages. This time there will not be much introduction to the languages, but instead experience reports, objective descriptions of what worked, what didn’t work and how you can improve your chances of success. The languages covered are Scala, Clojure, Ruby, Groovy and F#. Should be great fun.&lt;/p&gt;
&lt;p&gt;Hopefully I will have lots of time to see other presentations too. There are many I would love to see. ThoughtWorks also happens to be a sponsor of QCon, so there will be a booth where it’s a big possibility you can find me or my colleagues.&lt;/p&gt;
&lt;p&gt;I will do one day of RubyConf - the Saturday. Funnily enough I haven’t ever been to RubyConf, so I’m looking forward to this too.&lt;/p&gt;
&lt;p&gt;Finally, the first ever JRubyConf will happen next Sunday. The program looks really interesting. I’m going to be talking about testing, and also be part of the ending JRuby Core Team panel.&lt;/p&gt;
&lt;p&gt;I’m very excited about these conferences. Hope to see you there!&lt;/p&gt;</description>
	<pubDate>Thu, 12 Nov 2009 09:23:34 +0000</pubDate>
<feedburner:origLink>http://olabini.com/blog/2009/11/qcon-san-francisco-rubyconf-and-jrubyconf/</feedburner:origLink></item>
<item>
	<title>Simon Brunning: Links for 2009-11-11 [del.icio.us]</title>
	<guid isPermaLink="false">http://del.icio.us/brunns#2009-11-11</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/Yz3p8egU5NU/brunns</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/State_pattern"&gt;State pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://torontoist.com/2009/11/disgruntled_star_editor_takes_revenge.php"&gt;Disgruntled Star Editor Takes Constructive Revenge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://golang.org/"&gt;The Go Programming Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.hurryupharry.org/2009/11/11/the-sun-shows-how-easy-it-is-to-get-a-name-wrong/"&gt;The Sun Shows How Easy It Is To Get A Name Wrong&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://news.bbc.co.uk/1/hi/7090300.stm"&gt;Curvy women may be a clever bet&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Load of old tosh, but still...&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.guardian.co.uk/technology/gamesblog/2009/nov/09/dragon-age-origins-game-review"&gt;Dragon Age: Origins&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Looks fun - but I'll wait 'till it starts being discounted.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://faassen.n--tree.net/blog/view/weblog/2009/11/09/0"&gt;A history of Python packaging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.infoq.com/news/2009/11/agile-micromanagement"&gt;Agile is Micromanagement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://antwrp.gsfc.nasa.gov/apod/ap091111.html"&gt;Great Observatories Explore Galactic Center&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Beautiful.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/CubeSat"&gt;CubeSat&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
A CubeSat is a type of miniaturized satellite for space research that usually has a volume of exactly one liter (10 cm cube), weighs no more than one kilogram, and typically uses commercial off-the-shelf electronics components.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.guardian.co.uk/technology/2009/nov/10/rupert-murdoch-charging-for-internet"&gt;Rupert Murdoch: for whom the net tolls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.planetary.org/programs/projects/innovative_technologies/solar_sailing/"&gt;LightSail&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
The Planetary Society is building a spacecraft that will sail on sunlight alone by the end of 2010.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.newscientist.com/article/dn18138-backward-star-aint-from-around-here.html"&gt;Backward star ain't from around here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.wired.com/geekdad/2009/11/10-geeky-laws-that-should-exist-but-dont/"&gt;10 Geeky Laws That Should Exist, But Don’t | GeekDad | Wired.com&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Munroe’s Law: A person in a geeky argument who can quote xkcd to support his position automatically wins the argument.&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Thu, 12 Nov 2009 08:00:00 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/SmallValuesOfCool/~3/ynAeuhafaOE/brunns</feedburner:origLink></item>
<item>
	<title>Patrick Kua: What they don’t tell you about user stories</title>
	<guid isPermaLink="false">http://www.thekua.com/atwork/?p=785</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/n5n_H9xNA_s/</link>
	<description>&lt;p&gt;&lt;a href="http://www.thekua.com/atwork/wp-content/uploads/2009/11/Shh.jpg" rel="lightbox[pics785]" title="Shh"&gt;&lt;img src="http://www.thekua.com/atwork/wp-content/uploads/2009/11/Shh.jpg" alt="Shh" height="167" style="float: right;" width="250"&gt;&lt;/img&gt;&lt;/a&gt;Agile methods have a gap on how to do deal with requirements that often leaves business analysts confused about what to do. From an analyst’s point of view, user stories seem to be the only technique agile methods prescribe. When people are new to agile, they take this as agile’s “only” way of modelling requirements. What isn’t made explicit often gets forgotten, so I want to make this clear: Agile methods don’t discourage thorough analysis or modelling. They don’t discourage the use of diagrams and other visualisations that help people better understand and refine their domain representation. They want everyone to focus on value and communication by using the rights tools for the job. &lt;/p&gt;
&lt;p&gt;When coaching analysts, I often find myself telling them, all the tools they draw upon to question, to challenge, to refine and capture their understanding is important. Agile methods focus on better understanding of value, not better note taking. Writing things down does not automatically translate into understanding between two people. &lt;a href="http://www.agilemodeling.com/essays/communication.htm#Figure1"&gt;Cockburn’s&lt;/a&gt; already demonstrated a model that talks about the richness of communication methods, with written documentation being one of the worst.&lt;/p&gt;
&lt;p&gt;The best business analysts I’ve worked with have little need to write things down, having absorbed what needs to be done, understood the real requirements, and constantly available ready to help clarify them. Conversely, the worst business analysts see their job only as writing “requests” and “demands” down, doing little to question and challenge what is really needed versus what is merely articulated. These I call overpaid scribes. &lt;/p&gt;
&lt;p&gt;Question what value your tools are using and if they help you either better understand or better communicate with other people. If you find modelling in UML helps you better see relationships, do so but avoid spending all your time polishing the model and getting the syntax correct. Be wary of investing yourself too much in one particular model or document that makes you potentially more resistant to changing it. Neal Ford describes this as &lt;a href="http://memeagora.blogspot.com/2008/12/irrational-artifact-attachment.html"&gt;Irrational Artefact Attachment&lt;/a&gt;. If you find yourself writing something down to remind yourself of what is important to get across, do so but don’t use it as a way to avoid helping others understand it.&lt;/p&gt;
&lt;p&gt;Agile methods appear nebulous to many people because “user stories” simply appear. It’s not prescriptive about how you get there because there are simply too many different ways to get there. Whilst being prescriptive will help some projects, it would no doubt hurt many others.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Image of Shh! taken from &lt;a href="http://www.flickr.com/photos/gattine/2501150480/"&gt;Anthony Gattine’s&lt;/a&gt; flickr stream under the Creative Commons Licence&lt;/em&gt;&lt;/p&gt;</description>
	<pubDate>Thu, 12 Nov 2009 06:00:02 +0000</pubDate>
<feedburner:origLink>http://www.thekua.com/atwork/2009/11/what-they-dont-tell-you-about-user-stories/</feedburner:origLink></item>
<item>
	<title>James Crisp: HTML to PDF Conversion Plugin For Rails (A fork of wicked pdf)</title>
	<guid isPermaLink="false">http://jamescrisp.org/2009/11/12/html-to-pdf-conversion-plugin-for-rails-a-fork-of-wicked-pdf/</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/Jgy8Dj0Os8s/</link>
	<description>&lt;p&gt;Once a business web application reaches a certain size, the need often arises to generate PDFs from HTML/CSS. &lt;/p&gt;
&lt;p&gt;Up until recently, the story around this for a MRI Rails application was not good. You could either use tools like &lt;a href="http://prawn.majesticseacreature.com/"&gt;Prawn&lt;/a&gt;, which require a description of the layout in a specific DSL, or pay for a tool like &lt;a href="http://www.princexml.com/"&gt;Prince XML&lt;/a&gt; which can convert from HTML, but which costs quite a bit. Those using &lt;a href="http://jruby.org/"&gt;JRuby&lt;/a&gt; were in a stronger position as they could use the Java PDF library called &lt;a href="https://xhtmlrenderer.dev.java.net/"&gt;Flying Saucer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The good news is that PDF generation for MRI Ruby is now easy and free, thanks to &lt;a href="http://webkit.org/"&gt;webkit&lt;/a&gt;, the open source webkit wrapper called &lt;a href="http://code.google.com/p/wkhtmltopdf/"&gt;wkhtmltopdf&lt;/a&gt; and &lt;a href="http://mileszs.com/blog/2009/06/17/wicked-pdf-plugin.html"&gt;mileszs's wickedpdf plugin&lt;/a&gt;. I was really excited to come across this plugin and started to use it right away. However, it had a couple of issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Temp file handling caused errors when two PDFs were being generated within the same second (eg, 2 requests at almost the same time)&lt;/li&gt;
&lt;li&gt;Problems generating PDF were not reported&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://github.com/galdomedia/wicked_pdf"&gt;Galdomedia&lt;/a&gt; forked the code and updated it to use standard Ruby temp files. This was great for ruby 1.7, but not good for Ruby 1.6 which does not allow you to set the extension on temp files (wkhtmltopdf relies on having a .html extension). &lt;/p&gt;
&lt;p&gt;As my production servers run Ruby 1.6, I needed a different approach. &lt;a href="http://github.com/jcrisp/wicked_pdf"&gt;My fork&lt;/a&gt; uses streams rather than temporary files, and adds some basic error handling and basic integration tests.&lt;/p&gt;
&lt;p&gt;To install in a rails app:&lt;/p&gt;
&lt;pre&gt;script/plugin install git://github.com/jcrisp/wicked_pdf.git
&lt;/pre&gt;
&lt;p&gt;Or &lt;a href="http://github.com/jcrisp/wicked_pdf"&gt;clone the code from GitHub&lt;/a&gt;.
&lt;/p&gt;</description>
	<pubDate>Thu, 12 Nov 2009 04:47:07 +0000</pubDate>
<feedburner:origLink>http://jamescrisp.org/2009/11/12/html-to-pdf-conversion-plugin-for-rails-a-fork-of-wicked-pdf/</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009: Kim Zibrick's session on Business Alignment: Focus on the Workplace ...Not the Classroom!</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-3784743730097877566</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/CB6vUuyqwSM/devlearn-2009-kim-zibricks-session-on.html</link>
	<description>The last session I attended today was Kim Ziprik's short talk on &lt;em&gt;"Business Alignment: Focus on the Workplace ...Not the Classroom!"&lt;/em&gt;. Kim took aim at the tendency of training departments to &lt;em&gt;"train their way out"&lt;/em&gt; of a performance problem and how that has very little impact on actual workplace performance. She went onto talk about approaches that may be useful to bring the focus back to the workplace, where most learning happens.&lt;br&gt;&lt;/br&gt;&lt;h3&gt;What did I learn?&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;There are tremendous challenges that training teams are facing as a consequence of the changing pace of businsess:&lt;ul&gt;&lt;li&gt;performance variables;&lt;/li&gt;&lt;li&gt; learner motivation; &lt;/li&gt;&lt;li&gt; change of business situation; &lt;/li&gt;&lt;li&gt; retention drops drastically a short time after a training event. &lt;/li&gt;&lt;li&gt; training doesn't address the entire value stream and looks at localised optimisations &lt;/li&gt;&lt;li&gt; training is a cost based exercise that traditionally doesn't focus on workpplace performance whereas we should be investing in learning which is geared at solving challenges in the workplace&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Kim talked about creating &lt;em&gt;"Learning Wells and not Training Dams"&lt;/em&gt;:&lt;ul&gt;&lt;li&gt; drive what people need via their experience levels. She gave tips very similar to the ones I used in my older post about the &lt;a href="http://cipher-quaker.blogspot.com/2009/08/using-dreyfus-model-to-engage-people-in.html"&gt;Dreyfus Model&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Leverage performance based tools like:&lt;ul&gt;&lt;li&gt; Job Aids (&lt;a href="http://www.trainingwithinindustry.net/SW.html"&gt;Standard Work&lt;/a&gt;?);&lt;/li&gt;&lt;li&gt; Employee Performance and Support Systems;&lt;/li&gt;&lt;li&gt; Self Assessments; &lt;/li&gt;&lt;li&gt; Coaching; &lt;/li&gt;&lt;li&gt; Communities; &lt;/li&gt;&lt;li&gt; Career based curriculum&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; Integrate learning into the workplace - create &lt;a href="http://cipher-quaker.blogspot.com/2009/11/put-your-learners-on-diet-consider-pull.html"&gt;continuous learning opportunities&lt;/a&gt;.&lt;/li&gt;&lt;li&gt; Redesign your Learning Architecture. Rethink the roles your training team plays, the places where training happens, the measures for effectiveness, technologies assisting learning and the culture that surrounds these experiences. &lt;/li&gt;&lt;li&gt; Reduce the dependency on a single source of information. Harness the power of the collective - people together are far smarter than you can ever be.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-3784743730097877566?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 12 Nov 2009 02:36:41 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/Gnrxr1laDVo/devlearn-2009-kim-zibricks-session-on.html</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009 - Ruth Clark's session on Evidence Based Training</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-2781593217631615498</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/HPdOq2BMi_E/devlearn-2009-ruth-clarks-session-on.html</link>
	<description>The first concurrent session that I attended this morning was &lt;a href="http://www.clarktraining.com/"&gt;Ruth Clark&lt;/a&gt;'s talk about Evidence based Training. Ruth talked about moving from fads and fiction to facts about the use of multimedia in training and education. Ruth as usual was her confident, articulate self and displayed some wonderful research and evidence that contradicts a lot of traditional wisdom&lt;br&gt;&lt;/br&gt;&lt;h3&gt;What did I learn?&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Learning styles are overrated and a waste of time. There's no relationship between someone's learning style and their eventual performance on the job. eg: being a visual learner doesn't mean that you will have a high recall of an image.&lt;/li&gt;&lt;li&gt; Liking a session has no correlation to an individual's learning in the session. A highly rated session may not be the most effective.&lt;/li&gt;&lt;li&gt;People need the bare minimum detail to apply the learning. Extraneous detail is confusing (war stories, anecdotes, etc) and while immensely likeable, can hurt learning.&lt;/li&gt;&lt;li&gt;Tips for use of multimedia in elearning and training:&lt;ul&gt;&lt;li&gt;Graphics with text create the highest impact learning because of the dual encoding phenomenon. This is a great mode for novices and apprentices.&lt;/li&gt;&lt;li&gt; Audio narration is proven as the most effective method of providing descriptions to graphics. This should be the default on elearning courses, with the ability to pause, and turn off.&lt;/li&gt;&lt;li&gt; Simple line drawings are much easier to recall than complex 3D pictures. &lt;/li&gt;&lt;li&gt; Stills are often more effective than animation, to explain how things work. In such situations, animations put the brain in a passive state and create extraneous mental load&lt;/li&gt;&lt;li&gt; Videos are proven to be effective in teaching social skills and motor skills and to show examples.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-2781593217631615498?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 12 Nov 2009 02:10:03 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/BYyp7C42tl8/devlearn-2009-ruth-clarks-session-on.html</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009 - Andrew McAfee's Keynote. Enterprise 2.0 - the state of the art</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-7330590076290515865</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/Jz2HmPv0lQ4/devlearn-2009-andrew-mcafees-keynote.html</link>
	<description>This morning I sat through the most awesome keynote by Andrew McAfee - author of &lt;a href="http://www.amazon.com/Enterprise-2-0-Collaborative-Organizations-Challenges/dp/1422125874/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1257987677&amp;amp;sr=1-1"&gt;Enterprise 2.0: New Collaborative Tools for Your Organization's Toughest Challenges&lt;/a&gt;. Andrew is one of &lt;a href="http://www.eweek.com/c/a/IT-Management/100-Most-Influential-People-in-IT"&gt;the 100 most influential people in IT&lt;/a&gt;. His talk was not just informative and eye-opening, it was immensely entertaining. In short it was a privilege.&lt;br&gt;&lt;/br&gt;&lt;h3&gt;What did I learn?&lt;/h3&gt;Andrew's talk deserves a fairly long post (though with very random thoughts). His address was in 3 parts; the definition of Enterprise 2.0, the "state of the art" as he saw it and the things to avoid (&lt;em&gt;"how to snatch defeat from the jaws of victory"&lt;/em&gt;)&lt;h4&gt;The Definition of Enterprise 2.0&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Involves use of emergent technology or new uses of technology or social software;&lt;/li&gt;&lt;li&gt;Solves business problems and answers business goals&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;The State of the Art&lt;/h4&gt;Andrew defined the state of the art of Enterprise 2.0 under 6 major headings:&lt;h5&gt;Altruism&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;People want to help each other&lt;/li&gt;&lt;li&gt;Enterprise software needs to be people centric not document centric&lt;/li&gt;&lt;li&gt;The paranoia about risks is not senseless, but overrated. Most risks never materialise because in the enterprise, you don't have the luxury of being anonymous like on the web. People are unlikely to do the "wrong" things. In fact they never do it.&lt;/li&gt;&lt;li&gt;The entry barrier for people to want to help each other, needs to be low -- eg: &lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt;. People can help each other and do that within just 140 characters!&lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;Process&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;There's rarely one best way to do things in today's business world -- the era of best practices is dying.&lt;/li&gt;&lt;li&gt;People need to have the ability to self select and self organise when contributing content and deciding how and when to collaborate.&lt;/li&gt;&lt;li&gt; We need to limit workflow - it can't take several levels of approval to do something simple.&lt;/li&gt;&lt;li&gt; Structure shouldn't be imposed. Tools need to facilitate structure and structure should develop over time.&lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;Innovation&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;Example: &lt;a href="http://www.innocentive.com/"&gt;Innocentive&lt;/a&gt;, the idea of crowdsourced innovation, where its only a matter of getting a different person to take a look at your problem and solve it for much less than the solution is really worth!&lt;/li&gt;&lt;li&gt;Getting more eyeballs to look at a problem often generates more solutions. &lt;/li&gt;&lt;li&gt; Expertise is emergent, not identified. Anyone can be an expert and people are recognised for their contribution and not their position/ credentials.&lt;/li&gt;&lt;li&gt; Communities should be the one that people want. Nothing should be imposed. (Something someone said "Communities of interest" vs "Communities of Practice")&lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;Intelligence&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;Harness the collective. The wisdom of crowds makes decision making really powerful.&lt;/li&gt;&lt;li&gt; Peer decision making, peer reviews, peer innovation and peer feedback make ultimate sense (given the number of eyeballs looking at the issue!)&lt;/li&gt;&lt;li&gt;Andrew gave the example of the prediction market's analysis of the Obama campaign where crowdsourced probabilities resulted in a more accurate prediction of the election results than the most sophisticated analysis by expert statisticians.&lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;Benefits&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;Enterprise 2.0 gives you the opportunity to "narrate your work" to the extent that you can all of a sudden demonstrate your expertise.&lt;/li&gt;&lt;li&gt;It creates for better social connections. You are connected to the right people sooner.&lt;/li&gt;&lt;li&gt; It offers the opportunity to benefit from varied perspectives on a certain topic.&lt;/li&gt;&lt;/ul&gt;&lt;h5&gt;Impact&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;Results of a McKinsey study about web 2.0 tools shows:&lt;ul&gt;&lt;li&gt;Access to knowledge 68%&lt;/li&gt;&lt;li&gt;Access to internal experts 43%&lt;/li&gt;&lt;li&gt;Employee satisfaction 35%&lt;/li&gt;&lt;li&gt;Increased innovation 25%&lt;/li&gt;&lt;li&gt;Increased customer satisfaction 43%&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt; Its a bad idea to sit out the Web 2.0 phenomenon.&lt;/li&gt;&lt;li&gt; We need to look at technology with a fresh set of eyes. &lt;/li&gt;&lt;li&gt; We can't go back to "business as usual" after this recession.&lt;/li&gt;&lt;li&gt; Businesses need to leverage technology as one of its key components.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Things to Avoid&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Don't try to replace email: &lt;em&gt;Instead think of things that email cant do.&lt;/em&gt;&lt;/li&gt;&lt;li&gt; Don't accentuate the negatives:&lt;em&gt; Instead point out risks while accentuating the huge business benefits.&lt;/em&gt;&lt;/li&gt;&lt;li&gt; Don't fall in love with features: &lt;em&gt;Start simple, iterate through the solution&lt;/em&gt;&lt;/li&gt;&lt;li&gt; Don't declare war on the enterprise: &lt;em&gt;Its a bad sales strategy to alienate the very people that'll sponsor such a thing. Organisations need structure to function&lt;/em&gt;&lt;/li&gt;&lt;li&gt;Don't build walled gardens: &lt;em&gt;Instead allow multiple groups to flourish in the same place. Moving between groups needs to be seamless.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;Don't overuse the word "social": &lt;em&gt;It creates the wrong connotations for the business; especially in a time when we're seeking tangible results.&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-7330590076290515865?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 12 Nov 2009 01:53:38 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/9xXpZ8UwEM4/devlearn-2009-andrew-mcafees-keynote.html</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009 - Actions Speak Louder than Words, by Ethan Edwards</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-1928292348552717126</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/nN1yUdDT4h8/devlearn-2009-actions-speak-louder-than.html</link>
	<description>I just sat through a session called "Actions Speak Louder than words - Creating Meaningful e-Learning Interactions", by Ethan Edwards of Allen Interactions. The session was about interactions that create mental stimulation to eventually improve workplace performance. Ethan explained that an interaction has four aspects to it; namely Context, Challenge, Activity and Feedback. The focus of the session was on crafting and implementing meaningful challenges and activities for elearning.&lt;br&gt;&lt;/br&gt;&lt;h3&gt;What did I learn?&lt;/h3&gt;Ethan's session provided a balance of detail between instruction and demonstration. Here are a few things I'll remember.&lt;ul&gt;&lt;li&gt; A different style of presentations: Show and tell -- Ethan didn't just talk about his work, he actually showed real life examples of the interactions he's worked on. He embedded these as clickable links into the presentation and that made the entire experience almost seamless.&lt;/li&gt;&lt;li&gt;It helps to have some time aside to answer questions as a conference speaker. Ethan did pretty well to set aside almost 20 minutes for QnA. &lt;/li&gt;&lt;li&gt; On the content front, my big takeaway was Ethan's rules for elearning interaction design:&lt;ul&gt;&lt;li&gt; Measure an observable action.&lt;/li&gt;&lt;li&gt; The interaction should need attention and thought. This I feel is particularly important since a lot of elearning seems to be just a lot of click and turn!&lt;/li&gt;&lt;li&gt; The interaction should have relevance and meaning in the real world.&lt;/li&gt;&lt;li&gt; The interaction should allow the learner to model real world performance. &lt;/li&gt;&lt;li&gt; The interaction should require effort to complete. &lt;/li&gt;&lt;li&gt; And lastly, in keeping with my philosophy of "a safe environment to fail fast and learn from mistakes", the activity should be reversible. If a learner makes a mistake in elearning, it isn't the end of the world and we shouldn't be making the learner feel that way either!&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-1928292348552717126?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Wed, 11 Nov 2009 23:13:03 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/lcL_jyEhWE0/devlearn-2009-actions-speak-louder-than.html</feedburner:origLink></item>
<item>
	<title>Ross Pettit: Restructuring IT: Organizing for Results</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-30621875.post-2497962012261526550</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/hZ6J51Mq62c/restructuring-it-organizing-for-results.html</link>
	<description>&lt;p&gt;Up to this point in this &lt;a href="http://agilemanager.blogspot.com/search/label/Restructuring%20IT"&gt;series on Restructuring IT&lt;/a&gt;, we’ve looked at how IT has adopted an industrial model. IT has achieved scale, but at the cost of results, as is clear from the &lt;a href="http://agilemanager.blogspot.com/2009/06/case-for-restructuring-it.html"&gt;low rate of success&lt;/a&gt; of IT investments. We'll now take a look at how we can organize IT for results.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Professional versus Industrial&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;IT needs to reorganize for results, not scale. Organizing for results requires professionalism as opposed to industrialism.&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;table cellpadding="0" width="0" border="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://4.bp.blogspot.com/_GG5VW2cRMAY/Svj-imm38PI/AAAAAAAAAGU/8FjNZqdjr8s/s1600-h/assemblyline.JPG"&gt;&lt;img src="http://4.bp.blogspot.com/_GG5VW2cRMAY/Svj-imm38PI/AAAAAAAAAGU/8FjNZqdjr8s/s400/assemblyline.JPG" alt="" style="WIDTH: 287px; CURSOR: hand; HEIGHT: 172px;" border="0" id="BLOGGER_PHOTO_ID_5402347623463514354"&gt;&lt;/img&gt;&lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;a href="http://1.bp.blogspot.com/_GG5VW2cRMAY/Svj-rpgY9pI/AAAAAAAAAGc/jeKubXw6CSw/s1600-h/surgicalteam.JPG"&gt;&lt;img src="http://1.bp.blogspot.com/_GG5VW2cRMAY/Svj-rpgY9pI/AAAAAAAAAGc/jeKubXw6CSw/s400/surgicalteam.JPG" alt="" style="WIDTH: 291px; CURSOR: hand; HEIGHT: 170px;" border="0" id="BLOGGER_PHOTO_ID_5402347778860447378"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="2"&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;p align="center"&gt;&lt;em&gt;&lt;span style="font-size: 85%;"&gt;People in industrial and professional situations each use drills, but you wouldn’t staff an assembly line worker in an operating room to get "capacity" on a surgical team.&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;/br&gt;&lt;p&gt;To get professionalism, we need to organize less to try to be predictable (which will always escape us) and more to be responsive and accountable.&lt;/p&gt;&lt;p&gt;Let’s think about the things that would professionalize IT.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Instead of scrambling just before a deployment, what if every solution build acted as an internal gatekeeper of quality, continuously executing to validate technical, functional and non-functional completeness of everything we do? &lt;/li&gt;&lt;br&gt;&lt;/br&gt;&lt;li&gt;Instead of trying to “inspect quality” into IT, what if testing were a team responsibility, automated and integrated into what we do daily? &lt;/li&gt;&lt;br&gt;&lt;/br&gt;&lt;li&gt;Instead of watching big-up-front designs morph from whiteboard masterpiece to over-engineered Frankentecture, what if teams had the flexibility to take design decisions in near-JIT fashion, with a minimum of duplication and the fewest moving parts possible? &lt;/li&gt;&lt;br&gt;&lt;/br&gt;&lt;li&gt;Instead of a “requirements arms race” between business and IT, what if we were able to accommodate continuous business involvement, facilitated to enable continuous change management and adaptive project management?&lt;/li&gt;&lt;br&gt;&lt;/br&gt;&lt;li&gt;Instead of standing up volumes of impenetrable and unactionable requirements, what if we had short, business oriented requirements that could be quickly steered through development and QA and into production? &lt;/li&gt;&lt;br&gt;&lt;/br&gt;&lt;li&gt;Instead of sending round reams of paperwork for PMs to fill out in little more than CYA exercises, what if we were able to govern IT non-invasively, ascertaining from our delivery teams whether they’re delivering value for money, and working in accordance with expectations? &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We have the means by which to do all of these things. Today. Right now. But we can’t simply will them into place. To get these things, we need to restructure IT.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What does it really mean to “restructure”?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Before we discuss what restructuring IT is, let’s first understand what it isn’t. &lt;/p&gt;&lt;p&gt;Restructuring IT isn’t a question of org charts. All too often, new reporting lines just rearrange the deck chairs on the Titanic. It also isn’t about budgets, either: we can’t do more with less, because there isn’t that much less with which we can get any more done with.&lt;/p&gt;&lt;p&gt;How about the management cheerleading of recent years, things like “be close to your customer” and “have fewer hand-offs in your work processes.” When folks like &lt;a href="http://en.wikipedia.org/wiki/Tom_Peters"&gt;Tom Peters&lt;/a&gt; started putting those messages forward in the 1980s they were a wake-up call that business had gone adrift. And yes, we need to restructure with this in mind. But we can’t have reorganization by platitude. We need something actionable.&lt;/p&gt;&lt;p&gt;Restructuring IT is about behaviours. Changing behaviours away from industrial thinking to professional thinking is a pretty big shift. Among other things, it means each person is responsible not just for doing the tasks they’ve been assigned, but doing what is necessary for the project to succeed.&lt;/p&gt;&lt;p&gt;Think back to the surgical team metaphor. As my colleague Greg Reiser points out, the surgical team collaborates toward a shared objective, improving the quality of life of the patient. Their primary goal may be to graft blood vessels that bypass a coronary artery blockage, but their objective is to prolong the life of the patient. What does the team do when they discover, as they almost always do, that the condition of the heart and surrounding tissue is not exactly as they expected? They apply their professional expertise and work as a team to adapt in order to achieve the primary objective. This is how professionals behave.&lt;/p&gt;&lt;p&gt;It doesn’t help, of course, that there are so many headwinds to getting things done in IT, ranging from a constant cycle of upgrades that change points of integration to an abundant supply of people without the complete gene in their DNA. Results are hard. Finishing stuff is hard.&lt;/p&gt;&lt;p&gt;This begs a critical behavioural question: why take the risk of getting “results”? Why put yourself on the line, underwriting success with your personal guarantee, especially if you have a built-in scapegoat? I met with a team last year where the PM, BA and dev lead knew a project was going to fail, because the development team simply didn’t have the capability. The project leadership didn’t make any effort to change staff, because the decision of who to staff was somebody else’s: people were supplied to them by procurement. The project was conspicuous because it was late starting as it was, so their priority was to get started. Never mind that they knew it wouldn’t finish. In the end, they could say they simply played the hand they were dealt by the organizational structures – in this case, an industrial-inspired procurement function – that existed to make IT effort “cost effective.”&lt;/p&gt;&lt;p&gt;So rather than work to success, rather than pressing the button and stopping the line and saying “this project is going to fail and we need to do something about it before we make a commitment of capital and time” they simply got on with the work &lt;em&gt;knowing they were going to fail&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;This is all too common. There is structural disincentive to achieve results in a lot of IT organizations. This disincentive is supplemented with soft scrutiny. Most measures of “complete” amount to little more than people working to a state where nobody can tell them they’re not done, instead of working to a state where somebody can conclusively tell them they are done.&lt;/p&gt;&lt;p&gt;So what makes us think people will make the effort to get things done?&lt;/p&gt;&lt;p&gt;It also makes you wonder: how much of this is going on in your IT organization today?&lt;/p&gt;&lt;p&gt;In our next installment, we'll take a look at how, specifically, we restructure for results.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img src="https://blogger.googleusercontent.com/tracker/30621875-2497962012261526550?l=agilemanager.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Wed, 11 Nov 2009 16:24:56 +0000</pubDate>
	<author>noreply@blogger.com (Ross Pettit)</author>
<feedburner:origLink>http://agilemanager.blogspot.com/2009/11/restructuring-it-organizing-for-results.html</feedburner:origLink></item>
<item>
	<title>Mark Needham: Coding: Pushing the logic back</title>
	<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=1813</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/mfw5iuHOZSk/</link>
	<description>&lt;p&gt;I was reading &lt;a href="http://www.ur-ban.com/blog/2009/10/25/law-of-demeter-and-the-delegate-method/"&gt;a post on the law of demeter by Richard Hart&lt;/a&gt; recently and it reminded me that a lot of the refactorings that we typically do on code bases are about pushing the logic back into objects instead of exposing data and performing calculations elsewhere.&lt;/p&gt;
&lt;p&gt;An example that I spotted where we did this recently was while building a 'BusinessSummary' object whose state was based on the state of a collection of other objects.&lt;/p&gt;
&lt;p&gt;The code was keeping a count of the various states of the business objects:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; BusinessSummary buildSummaryObject&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
	BusinessSummary businessSummary &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; BusinessSummary&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
	&lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;BusinessObject businessObject &lt;span style="color: #339933;"&gt;:&lt;/span&gt; businessObjects&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
		State state &lt;span style="color: #339933;"&gt;=&lt;/span&gt; businessObject.&lt;span style="color: #006633;"&gt;getState&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
		&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;State.&lt;span style="color: #006633;"&gt;STATE_1&lt;/span&gt;.&lt;span style="color: #006633;"&gt;equals&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;state&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
			businessSummary.&lt;span style="color: #006633;"&gt;incrementState1&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;	
		&lt;span style="color: #009900;"&gt;}&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;State.&lt;span style="color: #006633;"&gt;STATE_2&lt;/span&gt;.&lt;span style="color: #006633;"&gt;equals&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;state&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
			businessSummary.&lt;span style="color: #006633;"&gt;incrementState2&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
		&lt;span style="color: #009900;"&gt;}&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
			&lt;span style="color: #666666; font-style: italic;"&gt;// and so on&lt;/span&gt;
		&lt;span style="color: #009900;"&gt;}&lt;/span&gt;					
	&lt;span style="color: #009900;"&gt;}&lt;/span&gt;	
	&lt;span style="color: #000000; font-weight: bold;"&gt;return&lt;/span&gt; businessSummary&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this example 'State' is an enum representing the state the 'BusinessObject' is currently in.&lt;/p&gt;
&lt;p&gt;Our first change to the code was to push the logic around state back into the 'BusinessObject' which results in the following code:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; BusinessSummary buildSummaryObject&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
	BusinessSummary businessSummary &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; BusinessSummary&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
	&lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;BusinessObject businessObject &lt;span style="color: #339933;"&gt;:&lt;/span&gt; businessObjects&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
		&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;businessObject.&lt;span style="color: #006633;"&gt;hasState1&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
			businessSummary.&lt;span style="color: #006633;"&gt;incrementState1&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;	
		&lt;span style="color: #009900;"&gt;}&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;businessObject.&lt;span style="color: #006633;"&gt;hasState2&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
			businessSummary.&lt;span style="color: #006633;"&gt;incrementState2&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
		&lt;span style="color: #009900;"&gt;}&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
			&lt;span style="color: #666666; font-style: italic;"&gt;// and so on&lt;/span&gt;
		&lt;span style="color: #009900;"&gt;}&lt;/span&gt;					
	&lt;span style="color: #009900;"&gt;}&lt;/span&gt;	
	&lt;span style="color: #000000; font-weight: bold;"&gt;return&lt;/span&gt; businessSummary&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;


&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; BusinessObject &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
	...
	&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;boolean&lt;/span&gt; hasState1&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
		&lt;span style="color: #000000; font-weight: bold;"&gt;return&lt;/span&gt; State.&lt;span style="color: #006633;"&gt;STATE_1&lt;/span&gt;.&lt;span style="color: #006633;"&gt;equals&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;state&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
	&lt;span style="color: #009900;"&gt;}&lt;/span&gt;
	...
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I think this is an improvement but it still isn't following the &lt;a href="http://www.pragprog.com/articles/tell-dont-ask"&gt;tell don't ask&lt;/a&gt; principle, we're just asking to be told about the data instead of asking for the data itself.&lt;/p&gt;
&lt;p&gt;We didn't have the time to do the next change where we would have got rid of the 'hasState' methods and just got the 'BusinessObject' to update the 'BusinessSummary' itself:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; BusinessSummary buildSummaryObject&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
	BusinessSummary businessSummary &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; BusinessSummary&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
	&lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;BusinessObject businessObject &lt;span style="color: #339933;"&gt;:&lt;/span&gt; businessObjects&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
		businessObject.&lt;span style="color: #006633;"&gt;writeTo&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;businessSummary&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;					
	&lt;span style="color: #009900;"&gt;}&lt;/span&gt;	
	&lt;span style="color: #000000; font-weight: bold;"&gt;return&lt;/span&gt; businessSummary&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;


&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; BusinessObject &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;final&lt;/span&gt; State state&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
	...
	&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; writeTo&lt;span style="color: #009900;"&gt;(&lt;/span&gt;BusinessSummary businessSummary&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
		&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;State.&lt;span style="color: #006633;"&gt;STATE_1&lt;/span&gt;.&lt;span style="color: #006633;"&gt;equals&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;state&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
			businessSummary.&lt;span style="color: #006633;"&gt;incrementState1&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;	
		&lt;span style="color: #009900;"&gt;}&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;State.&lt;span style="color: #006633;"&gt;STATE_2&lt;/span&gt;.&lt;span style="color: #006633;"&gt;equals&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;state&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
			businessSummary.&lt;span style="color: #006633;"&gt;incrementState2&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
		&lt;span style="color: #009900;"&gt;}&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
			&lt;span style="color: #666666; font-style: italic;"&gt;// and so on&lt;/span&gt;
		&lt;span style="color: #009900;"&gt;}&lt;/span&gt;
	&lt;span style="color: #009900;"&gt;}&lt;/span&gt;
	...
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looking back on this code having written this post I wonder whether we need to do the loop or whether it would be better to pass the collection of 'businessObjects' to the 'BusinessSummary' and let it take care of that logic instead.&lt;/p&gt;
&lt;p&gt;If we did that then we would need to expose 'hasState1′ and 'hasState2′ methods on 'BusinessObject' like on the first refactoring so that we could work out how to populate 'BusinessSummary'.&lt;/p&gt;
&lt;p&gt;I prefer the solution where 'BusinessObject' writes to the 'BusinessSummary' although it seems like 'BusinessObject' now has more than one reason to change – if it changes or if 'BusinessSummary' changes. This would violate the &lt;a href="http://blogs.agilefaqs.com/2009/10/19/single-responsibility-principle-demystified/"&gt;single responsibility principle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I discussed this with &lt;a href="http://intwoplacesatonce.com/"&gt;Dave&lt;/a&gt; and he pointed out that as long as the contract that 'BusinessSummary' and 'BusinessObject' have – i.e. the 'incrementState1′ and 'incrementState2′ methods – stays the same then it wouldn't really be a problem.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/MarkNeedham/~4/YQWSJ-DYBXY" height="1" width="1"&gt;&lt;/img&gt;</description>
	<pubDate>Wed, 11 Nov 2009 10:30:08 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/MarkNeedham/~3/YQWSJ-DYBXY/</feedburner:origLink></item>
<item>
	<title>Simon Brunning: Links for 2009-11-10 [del.icio.us]</title>
	<guid isPermaLink="false">http://del.icio.us/brunns#2009-11-10</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/yZTxF40cSxk/brunns</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://learn.genetics.utah.edu/content/begin/cells/scale/"&gt;Cell Size and Scale&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Awesome zoomable window.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/django-axes/"&gt;django-axes - Project Hosting on Google Code&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
"django-axes is a very simple way for you to keep track of failed login attempts, both for the Django admin and for the rest of your site."&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sass-lang.com/"&gt;Sass - Syntactically Awesome Stylesheets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Wed, 11 Nov 2009 08:00:00 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/SmallValuesOfCool/~3/DUS3hqkQ4Xc/brunns</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: DevLearn 2009 - Ruth Clark's workshop on Scenario Based Learning</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-1291981383387409769</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/dpm7vRhzs54/devlearn-2009-ruth-clarks-workshop-on.html</link>
	<description>Today was my second day at &lt;a href="http://www.elearningguild.com/content.cfm?selection=doc.1264"&gt;DevLearn 2009&lt;/a&gt; and I must say its been a great investment this far. If not for anything else, its been a great opportunity to meet a lot of great learning professionals not just from the United States, but from all across the world. The ideas and thoughts that we've shared will be of great value to my work back in Bangalore, India. Today I sat through the workshop by Ruth Clark on the topic of &lt;a href="http://www.clarktraining.com/content/articles/ScenarioBasedLearning.pdf"&gt;"Scenario Based Learning"&lt;/a&gt; and I thought I could do a quick report on some things I learnt from the experience.&lt;br&gt;&lt;/br&gt;&lt;h3&gt;What did I learn?&lt;/h3&gt;&lt;ul&gt;&lt;li&gt; Scenario based learning can be described as follows:&lt;ul&gt;&lt;li&gt;&lt;strong&gt;What&lt;/strong&gt;: Scenario based learning uses simulated, real life scenarios to trigger the acquisition and simultaneous application of a skill. It gives the learner the opportunity for &lt;em&gt;Whole-task practice&lt;/em&gt;. Whole task practice involves being able to combine various non-integrated parts of skills and information to put together a real-world, real-life performance. An example of whole task practice is the ability to put together a budget in Excel as against the part-tasks of editing cells, creating formulae, etc. Scenario based learning also allows for better &lt;em&gt;Far &lt;a href="http://coe.sdsu.edu/eet/Articles/transferLearn/start.htm"&gt;transfer&lt;/a&gt;&lt;/em&gt; &lt;a href="http://coe.sdsu.edu/eet/Articles/transferLearn/start.htm"&gt;of learning&lt;/a&gt; as against the procedural &lt;em&gt;near transfer&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;When&lt;/strong&gt;:Scenario based learning is effective in to simulate situations that are rare, strange, high-risk or impractical to simulate in a classroom or in the workplace.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Who&lt;/strong&gt;: Scenario based learning is best suited for Novices and Apprentices. The experts are perhaps the people that can help design this learning!&lt;/li&gt;&lt;/ul&gt;There's empirical evidence to suggest that Scenario based elearning benefits the most from rich multimedia additions, such as real life videos.&lt;/li&gt;&lt;li&gt;As with every other teaching strategy, its best not to use this as a silver bullet - consider your subject and your audience carefully before you deploy this approach.&lt;/li&gt;&lt;li&gt; Lastly, I learnt that to build a learning scenario, you need to consider and plan six factors in your design:&lt;br&gt;&lt;/br&gt;&lt;a href="http://dl.dropbox.com/u/478762/SBL.png"&gt;&lt;img src="http://dl.dropbox.com/u/478762/SBL.png" alt="" border="0" style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; cursor: hand; width: 510px; height: 313px;"&gt;&lt;/img&gt;&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;strong&gt;Task Deliverable&lt;/strong&gt;&lt;/strong&gt;: What will the learner do to demonstrate competence?&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Trigger Event&lt;/strong&gt;: How the task or problem normally initiates in the job setting.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Case Data&lt;/strong&gt;: What background information is needed to solve the case? &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Guidance&lt;/strong&gt;: How will learners get assistance when solving the case?&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Feedback&lt;/strong&gt;: How will the learners receive intrinsic feedback as the scenario plays out? How will they receive traditional, instructional feedback a.k.a &lt;em&gt;Teaching Moments&lt;/em&gt;?&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Reflection&lt;/strong&gt;: What opportunities will the learner have to review their actions/ decisions and consider alternatives?&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr&gt;&lt;/hr&gt;Overall, I think the workshop brought out some really interesting discussion and I think the various perspectives and styles that people applied to their own design situations was particularly amazing. I'll recommend Ruth's session to anyone that has the opportunity to attend in the future.&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-1291981383387409769?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Wed, 11 Nov 2009 07:01:34 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/vz5qY9DQcmA/devlearn-2009-ruth-clarks-workshop-on.html</feedburner:origLink></item>
<item>
	<title>Simon Brunning: Links for 2009-11-09 [del.icio.us]</title>
	<guid isPermaLink="false">http://del.icio.us/brunns#2009-11-09</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/R70eTuccfJY/brunns</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://jacobian.org/writing/the-power-of-no/"&gt;The power of "no"&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Is it Open Source versus Commercial that makes the difference, or a Benevolent Dictator? I'd say the latter.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.devco.net/archives/2009/11/06/test_driven_deployment_-_mcollective_puppet_cucumber.php"&gt;Test Driven Deployment&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Nice idea - but don't call it bleedin' TDD. FFS.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.guardian.co.uk/news/datablog/2009/nov/06/drugs-bnp"&gt;Drugs and the BNP&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Nice data visualization.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.guardian.co.uk/media/2009/nov/09/sidewiki-danger-to-pr"&gt;SideWiki changes everything&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.leosoto.com/2009/11/django-jython-100-released.html"&gt;Django-Jython 1.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://css-discuss.incutio.com/?page=FrontPage"&gt;Front Page - css-discuss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.guardian.co.uk/media/2009/nov/09/rupert-murdoch-google"&gt;Rupert Murdoch's threat unlikely to worry Google&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Tue, 10 Nov 2009 08:00:00 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/SmallValuesOfCool/~3/LUz_6UZ_ydU/brunns</feedburner:origLink></item>
<item>
	<title>Dahlia Bock: Working Effectively with Legacy Code (Robert C. Martin Series)</title>
	<guid isPermaLink="false">http://dahliabock.wordpress.com/?p=334</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/NYImgxT2emY/</link>
	<description>&lt;div class="snap_preview"&gt;&lt;br&gt;&lt;/br&gt;&lt;p&gt;&lt;a style="float: left; padding-right: 20px;" href="http://www.goodreads.com/book/show/44919.Working_Effectively_with_Legacy_Code"&gt;&lt;img src="http://photo.goodreads.com/books/1170271723m/44919.jpg" alt="Working Effectively with Legacy Code (Robert C. Martin Series)" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;a href="http://www.goodreads.com/book/show/44919.Working_Effectively_with_Legacy_Code"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.goodreads.com/book/show/44919.Working_Effectively_with_Legacy_Code"&gt;Working Effectively with Legacy Code by Michael Feathers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I’ve been carrying around this book with me for the past few weeks and I find myself going back and reading parts of a chapter again and again, trying to soak in the concepts. This particular chapter, titled: &lt;em&gt;I Don’t Have Much Time And I Have To Change It&lt;/em&gt;, struck me specifically when Feathers starts out talking about change and how often it happens in code bases and that steps should be taken to make every consequent change easier than the one before. When teams make it a point to only introduce changes to the code only if they have tests to cover that change, they find that their velocity slows down and people feel like they aren’t getting as much done as they need to. Feathers emphasizes that this is normal but if they persevere, they slowly realize that they are revisiting better code and changes get easier and easier to make.&lt;/p&gt;
&lt;p&gt;I think that it’s important for teams to understand the benefits of testable code and how it eases the process of change so that they will invest the time and energy needed to get the code to that point. And I quote:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;Ultimately, testing makes your work go faster, and that’s important in nearly every development organization.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Having code that is testable is only possible if we do one of the following (If I remember correctly, I think this is according to Uncle Bob):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Write the tests before writing the code&lt;/li&gt;
&lt;li&gt;Design for testability&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Doing the latter isn’t easy, and in fact it is so hard to achieve that people end up not doing it at all. So that leaves us with Option 1. But sometimes you come across code that doesn’t have any tests AND doesn’t look like it is testable, but you have to make some changes in a short amount of time. So what do you do? Michael Feathers suggests 4 approaches, and my colleague &lt;a href="http://www.markhneedham.com/blog/2009/10/26/book-club-working-effectively-with-legacy-code-chapters-6-7-michael-feathers/" target="_blank"&gt;Mark documents it in a short and sweet way&lt;/a&gt; (basically he beat me to writing the post first).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sprout Method&lt;br&gt;&lt;/br&gt;
Advantages: Separating new code from old code. New code is testable.&lt;br&gt;&lt;/br&gt;
Disadvantages: You’re giving up on the old code for now.&lt;/li&gt;
&lt;li&gt;Sprout Class&lt;br&gt;&lt;/br&gt;
Advantages: Allows you to move forward with more confidence.&lt;br&gt;&lt;/br&gt;
Disadvantages: Conceptual complexity – moving new code into a separate class disrupts the flow of how key classes in the code base work together.&lt;/li&gt;
&lt;li&gt;Wrap Method&lt;br&gt;&lt;/br&gt;
Advantages: A great way to introduce seams (this is a concept that Feathers talks about in a previous chapter, which we will visit in a later post) while adding new features.&lt;br&gt;&lt;/br&gt;
Disadvantages: This method requires you to rename the method that you want to change, and create a new method with the same name as the previous method before the rename was done. Sometimes this could introduce sloppy method names because we needed to do some renaming to make way for the new method.&lt;/li&gt;
&lt;li&gt;Wrap Class&lt;br&gt;&lt;/br&gt;
This method is pretty much the same as Wrap Method except you’re extracting new behavior out into a new class. Feathers mentioned that 2 things push him towards choosing to use Wrap Classes and one of them is when a class has grown so large that he cannot stand to make it worse. Pushing behavior into a new class when the existing class is unmanageably large could also indicate that the original class might have too many responsibilities and thus needs to be gutted.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I like this chapter because it formalizes a lot of things that I try to do very often because of the large range of code bases that I work with, but find it difficult to nail it down to something that could be explained to someone else.&lt;/p&gt;
  &lt;a href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/334/" rel="nofollow"&gt;&lt;img src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/334/" alt="" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/334/" rel="nofollow"&gt;&lt;img src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/334/" alt="" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/334/" rel="nofollow"&gt;&lt;img src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/334/" alt="" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/334/" rel="nofollow"&gt;&lt;img src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/334/" alt="" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/334/" rel="nofollow"&gt;&lt;img src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/334/" alt="" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;img src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&amp;amp;blog=4589287&amp;amp;post=334&amp;amp;subd=dahliabock&amp;amp;ref=&amp;amp;feed=1" alt="" border="0"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Tue, 10 Nov 2009 02:40:56 +0000</pubDate>
<feedburner:origLink>http://dahliabock.wordpress.com/2009/11/10/book-review-working-effectively-with-legacy-code-chapter-6/</feedburner:origLink></item>
<item>
	<title>Mark Needham: Legacy Code: Sensing</title>
	<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=1808</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/-2_TX16BQ9M/</link>
	<description>&lt;p&gt;In '&lt;a href="http://www.amazon.com/gp/product/0131177052?ie=UTF8&amp;amp;tag=marneesblo-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0131177052"&gt;Working Effectively With Legacy Code&lt;/a&gt;' Michael Feathers describes two reasons for wanting to break dependencies in our code – to allow &lt;a href="http://www.markhneedham.com/blog/2009/10/20/book-club-working-effectively-with-legacy-code-chapters-34-5-michael-feathers/"&gt;separation and sensing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The former describes the need to get a piece of code into a test harness while the latter describes the need to assert whether that piece of code is doing what we want it to.&lt;/p&gt;
&lt;p&gt;On the projects I've worked on we've tended to run into problems with the latter more frequently and Matt and I actually ran into this problem when we were &lt;a href="http://www.markhneedham.com/blog/2009/10/18/coding-role-based-interfaces/"&gt;refactoring some code into a role based interface approach&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We started with the following code:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="csharp"&gt;&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;class&lt;/span&gt; ApplicationController &lt;span style="color: #008000;"&gt;:&lt;/span&gt; Controller
&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
	&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;string&lt;/span&gt; BusinessType
	&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
		get &lt;span style="color: #000000;"&gt;{&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;return&lt;/span&gt; GetType&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;.&lt;span style="color: #0000FF;"&gt;Replace&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #666666;"&gt;"Controller"&lt;/span&gt;, &lt;span style="color: #666666;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
 
	&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;override&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;void&lt;/span&gt; OnActionExecuting&lt;span style="color: #000000;"&gt;(&lt;/span&gt;ActionExecutingContext context&lt;span style="color: #000000;"&gt;)&lt;/span&gt; 
	&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
    		&lt;span style="color: #0600FF;"&gt;base&lt;/span&gt;.&lt;span style="color: #0000FF;"&gt;OnActionExecuting&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;context&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
		ViewData&lt;span style="color: #000000;"&gt;[&lt;/span&gt;&lt;span style="color: #666666;"&gt;"SomeViewDataKey"&lt;/span&gt;&lt;span style="color: #000000;"&gt;]&lt;/span&gt; &lt;span style="color: #008000;"&gt;=&lt;/span&gt; CreateThatViewDataStuff&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
 
	&lt;span style="color: #0600FF;"&gt;private&lt;/span&gt; ViewDataStuff CreateThatViewDataStuff&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
		&lt;span style="color: #0600FF;"&gt;return&lt;/span&gt; &lt;span style="color: #008000;"&gt;new&lt;/span&gt; ViewDataStuff 
		&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
			Content &lt;span style="color: #008000;"&gt;=&lt;/span&gt; BuildContent&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
			&lt;span style="color: #008080; font-style: italic;"&gt;// and so on&lt;/span&gt;
		&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
 
	&lt;span style="color: #0600FF;"&gt;private&lt;/span&gt; IContent BuildContent&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
		&lt;span style="color: #0600FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;BusinessType &lt;span style="color: #008000;"&gt;==&lt;/span&gt; &lt;span style="color: #666666;"&gt;"BusinessType1"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
		&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
			&lt;span style="color: #0600FF;"&gt;return&lt;/span&gt; CreateContentForBusinessType1&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
		&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
		&lt;span style="color: #0600FF;"&gt;else&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;BusinessType &lt;span style="color: #008000;"&gt;==&lt;/span&gt; &lt;span style="color: #666666;"&gt;"BusinessType2"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
		&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
			&lt;span style="color: #0600FF;"&gt;return&lt;/span&gt; CreateContentForBusinessType2&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
		&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
		&lt;span style="color: #0600FF;"&gt;else&lt;/span&gt;
		&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
			&lt;span style="color: #0600FF;"&gt;return&lt;/span&gt; CreateContentForEveryOtherBusinessType&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
		&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The 'BuildContent' method is the one that we're really interested in here but it's a private method on the controller so we currently don't have an easy way to assert that it's being created correctly.&lt;/p&gt;
&lt;p&gt;In order to test that functionality more easily we decided to make the method public so we could just call it directly. &lt;/p&gt;
&lt;p&gt;We wanted to do this so that we could write some tests around this bit of functionality before we refactored it so that we could be sure we hadn't broken the way it worked while doing so.&lt;/p&gt;
&lt;p&gt;As &lt;a href="http://hamletdarcy.blogspot.com/2009/06/forgotten-refactorings.html"&gt;Hamlet D'Arcy points out, if we're going to call it refactoring then we need to make sure that we're protected by tests&lt;/a&gt;. Otherwise we're just changing stuff.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="csharp"&gt;&lt;span style="color: #000000;"&gt;[&lt;/span&gt;Test&lt;span style="color: #000000;"&gt;]&lt;/span&gt;
&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;void&lt;/span&gt; ShouldCreateContent&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
	var someRepository &lt;span style="color: #008000;"&gt;=&lt;/span&gt; MockRepository.&lt;span style="color: #0000FF;"&gt;CreateMock&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;lt;&lt;/span&gt;ISomeRepository&lt;span style="color: #008000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
 
	var controller &lt;span style="color: #008000;"&gt;=&lt;/span&gt; &lt;span style="color: #008000;"&gt;new&lt;/span&gt; BusinessType1Controller&lt;span style="color: #000000;"&gt;(&lt;/span&gt;someRepository&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
 
	someRepository.&lt;span style="color: #0000FF;"&gt;Expect&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;s &lt;span style="color: #008000;"&gt;=&amp;gt;&lt;/span&gt; s.&lt;span style="color: #0000FF;"&gt;GetBusinessType1Message&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;.&lt;span style="color: #0600FF;"&gt;Return&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #666666;"&gt;"someValue"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
 
	var content &lt;span style="color: #008000;"&gt;=&lt;/span&gt; controller.&lt;span style="color: #0000FF;"&gt;BuildContent&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
 
	&lt;span style="color: #008080; font-style: italic;"&gt;// and so on	&lt;/span&gt;
&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We did the same for the other business types as well.&lt;/p&gt;
&lt;p&gt;I normally don't like making private methods public but we didn't intend to checkin our code until the refactoring was complete at which point the method would be made private again. &lt;/p&gt;
&lt;p&gt;The code ended up something like this:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="csharp"&gt;&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;class&lt;/span&gt; BusinessType1Controller &lt;span style="color: #008000;"&gt;:&lt;/span&gt; ApplicationController
&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
	&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;override&lt;/span&gt; IContent CreateContent&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
		&lt;span style="color: #0600FF;"&gt;return&lt;/span&gt; &lt;span style="color: #008000;"&gt;new&lt;/span&gt; BusinessType1Content&lt;span style="color: #000000;"&gt;(&lt;/span&gt;someRepository&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;


&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="csharp"&gt;&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;class&lt;/span&gt; BusinessType1Content &lt;span style="color: #008000;"&gt;:&lt;/span&gt; IContent
&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
	&lt;span style="color: #0600FF;"&gt;private&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;readonly&lt;/span&gt; ISomeRepository someRepository&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
 
	&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; BusinessType1Content&lt;span style="color: #000000;"&gt;(&lt;/span&gt;ISomeRepository someRepository&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
		&lt;span style="color: #0600FF;"&gt;this&lt;/span&gt;.&lt;span style="color: #0000FF;"&gt;someRepository&lt;/span&gt; &lt;span style="color: #008000;"&gt;=&lt;/span&gt; someRepository&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
 
	&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;string&lt;/span&gt; GetMessage&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
		&lt;span style="color: #008080; font-style: italic;"&gt;// this would be a different repository call for other business types&lt;/span&gt;
		&lt;span style="color: #0600FF;"&gt;return&lt;/span&gt; someRepository. &lt;span style="color: #0000FF;"&gt;GetBusinessType1Message&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We were able to create a test against the business types directly instead of having to write a test against the controller:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="csharp"&gt;&lt;span style="color: #000000;"&gt;[&lt;/span&gt;Test&lt;span style="color: #000000;"&gt;]&lt;/span&gt;
&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;void&lt;/span&gt; ShouldCreateContent&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
	var someRepository &lt;span style="color: #008000;"&gt;=&lt;/span&gt; MockRepository.&lt;span style="color: #0000FF;"&gt;CreateMock&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;lt;&lt;/span&gt;ISomeRepository&lt;span style="color: #008000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
 
	var content &lt;span style="color: #008000;"&gt;=&lt;/span&gt; &lt;span style="color: #008000;"&gt;new&lt;/span&gt; Content&lt;span style="color: #000000;"&gt;(&lt;/span&gt;someRepository&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
 
	someRepository.&lt;span style="color: #0000FF;"&gt;Expect&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;s &lt;span style="color: #008000;"&gt;=&amp;gt;&lt;/span&gt; s.&lt;span style="color: #0000FF;"&gt;GetBusinessType1Message&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;.&lt;span style="color: #0600FF;"&gt;Return&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #666666;"&gt;"someValue"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
 
	var message &lt;span style="color: #008000;"&gt;=&lt;/span&gt; controller.&lt;span style="color: #0000FF;"&gt;GetMessage&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
 
	&lt;span style="color: #008080; font-style: italic;"&gt;// and so on	&lt;/span&gt;
&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Having got these new tests passing the ones we'd written against 'BuildContent' now also worked and since they were effectively testing the same thing we were able to get rid of them and make 'BuildContent' private again.&lt;/p&gt;
&lt;p&gt;Despite the fact that I was initially reluctant to expose the 'BuildContent' method this approach seemed to work out reasonably well.&lt;/p&gt;
&lt;p&gt;An alternative approach would have been to create a test only ApplicationController and then create a method on that which called the 'OnActionExecuting' method.&lt;/p&gt;
&lt;p&gt;We've done that to test some other things and it would have allowed us to test the creation of 'Content' in a more roundabout way without needing to make 'BuildContent' public.&lt;/p&gt;
&lt;p&gt;The additional effort involved in doing that for not much gain means that given a similar situation in the future I'd probably use just make the method public again!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/MarkNeedham/~4/7bO5AFwq4DA" height="1" width="1"&gt;&lt;/img&gt;</description>
	<pubDate>Mon, 09 Nov 2009 20:33:22 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/MarkNeedham/~3/7bO5AFwq4DA/</feedburner:origLink></item>
<item>
	<title>Jie Xiong: 测试驱动咨询</title>
	<guid isPermaLink="false">tag:gigix.thoughtworkers.org,2009-11-09:647</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/jtRVRUcce2o/test-driven-consulting</link>
	<description>&lt;p&gt;当别人求助你解决一个问题时，第一件要做的是什么？&lt;/p&gt;


	&lt;p&gt;不是挽起袖子解决问题。不是诊断症结在哪儿。甚至都不是问5个why。&lt;/p&gt;


	&lt;p&gt;首先要问的问题是：&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;如果这是一个问题，用什么数据能体现它？&lt;/li&gt;
		&lt;li&gt;如果问题被修复了，从这个数据上是否能反映？&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;然后，把度量放下去。每个度量项要有几个要素：&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;哪些数据？&lt;/li&gt;
		&lt;li&gt;如何得到数据？&lt;/li&gt;
		&lt;li&gt;以什么频率采集数据？&lt;/li&gt;
		&lt;li&gt;如何发布结果？&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;按照这几个要素制定一个跟踪度量方案。用这个方案先采集现有数据。根据现有数据定一个改进目标。&lt;/p&gt;


	&lt;p&gt;这就是你的──正在失败的──测试。先把测试放下去，然后再提任何改进措施。&lt;/p&gt;</description>
	<pubDate>Mon, 09 Nov 2009 14:26:07 +0000</pubDate>
<feedburner:origLink>http://gigix.thoughtworkers.org/2009/11/9/test-driven-consulting</feedburner:origLink></item>
<item>
	<title>Thomas Czarniecki: HTTP method primer for RESTful web services</title>
	<guid isPermaLink="false">http://watchitlater.com/blog/?p=72</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/GgYFb_x99X8/72</link>
	<description>&lt;p&gt;The following is just a reminder to stop me from getting confused &lt;img src="http://watchitlater.com/blog/wp-includes/images/smilies/icon_wink.gif" alt=";-)" class="wp-smiley"&gt;&lt;/img&gt; &lt;/p&gt;
&lt;p&gt;GET&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Used to fetch a resource.&lt;/li&gt;
&lt;li&gt;The server sends back a representation of the resource in the response body.&lt;/li&gt;
&lt;li&gt;Safe operation (see below).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DELETE&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Used to delete a resource.&lt;/li&gt;
&lt;li&gt;The response from a server may contain a status message or nothing at all. It is usually nice to send back at least a 204 (No Content).&lt;/li&gt;
&lt;li&gt;Idempotent operation (see below).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PUT&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Used to create or modify a resource. If your server should not permit users to determine the URI of a new resource then you may need to create it via a POST to a factory service (see below).&lt;/li&gt;
&lt;li&gt;The request body contains the proposed new representation of the resource.&lt;/li&gt;
&lt;li&gt;From my reading there seems to be some contention as to whether the request body should contain a full representation of the resource or a delta when modifying an existing resource. My personal preference is that the request should contain a representation of the whole resource, and use a POST method to the resource to update part of a resource. Alternatively, if possible, you can PUT to a sub-resource (e.g. PUT to /user/12345/address if all I want to do is modify the user’s address).&lt;/li&gt;
&lt;li&gt;The response from a server may contain a status message or nothing at all. It is usually nice to at least return a 200 (OK).&lt;/li&gt;
&lt;li&gt;Idempotent operation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;POST&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; Used to create subordinate resources: resources that exist in relation to some other parent resource.
&lt;ul&gt;
&lt;li&gt;For example: POST /weblogs/myweblog with the request body containing the contents of a new weblog entry would create an entry called /weblogs/myweblog/entries/SS0093WSA.&lt;/li&gt;
&lt;li&gt;Response to such a POST request usually has a status of 201 (Created) and a HTTP response “Location” header that has the URI of the created resource.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;POST can also be used to append to an existing resource or to update an existing resource.
&lt;ul&gt;
&lt;li&gt;For example: POST to /log adds a log message to the /log resource.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Not safe or idempotent. Expect side-effects. “Here be dragons”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HEAD&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Used to retrieve metadata about a resource, rather than the resource itself.&lt;/li&gt;
&lt;li&gt;Can be used to check if the resource exists, or if a newer version of the resource is available.&lt;/li&gt;
&lt;li&gt;Gives you the same HTTP header as the response to a GET request, just without the response body.&lt;/li&gt;
&lt;li&gt;Safe operation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OPTIONS and TRACE&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Currently not really used by most RESTful systems. Nobody can really figure out how to use them properly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OPERATION TYPES&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Safe operation&lt;/dt&gt;
&lt;dd&gt;Should not change any server state – or at least any state that matters as even GET requests can get logged or access counters can become incremented.&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl&gt;
&lt;dt&gt;Idempotent operation&lt;/dt&gt;
&lt;dd&gt;Has the same effect irrespective of the number of times its applied. In other words, the second and subsequent requests leave the resource in exactly the same state as the first request did. &lt;/dd&gt;
&lt;/dl&gt;</description>
	<pubDate>Mon, 09 Nov 2009 11:41:20 +0000</pubDate>
<feedburner:origLink>http://watchitlater.com/blog/archives/72</feedburner:origLink></item>
<item>
	<title>Ola Bini: A week at Øredev</title>
	<guid isPermaLink="false">http://olabini.com/blog/?p=684</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/yUDfzZaJVOY/</link>
	<description>&lt;p&gt;I just came back from 10 days in Malmö, Sweden, for the Øredev conference. I’ve had a great time. Part of that was because I had Stella with me, and she got to meet all my conference-friends, so that was nice.&lt;/p&gt;
&lt;p&gt;But a big part of it is basically just the fact that Øredev is an outstanding conference.&lt;/p&gt;
&lt;p&gt;Some of my impressions, things I learned and did in no specific order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hadoop is really cool and I wish I had time to learn more about it. Alex Loddengaard from Cloudera did a very good job introducing this technology in his tutorial. We got to do way fun stuff!&lt;/li&gt;
&lt;li&gt;People liked my talk about Ioke - and I was very happy with how it went too.&lt;/li&gt;
&lt;li&gt;Stuart Halloway is really good at introducing Clojure - I’m looking forward to his talk at QCon SF even more now.&lt;/li&gt;
&lt;li&gt;Me, Tyler Jennings, Neal Ford, Dan North and Stuart Halloway spent several hours of BoF time to create a new BDD framework for Clojure - this was way fun hacking, interesting from a group management and design perspective and just plain fun. There is a distinct possibility that me and Neal will give a talk at the TW US Away Day about this, if anyone is interested.&lt;/li&gt;
&lt;li&gt;Ze Frank is amazing. Really great evening keynote/entertainment.&lt;/li&gt;
&lt;li&gt;Niclas Nilsson and Hans Brattberg did a very accurate depiction of common problems and failure modes of pair programming. Good stuff.&lt;/li&gt;
&lt;li&gt;Tyler Jennings gave an introduction to Software Craftsmanship. Glad I didn’t miss this presentation. Very nicely done.&lt;/li&gt;
&lt;li&gt;Kevlin Henney did a great presentation about agile modeling. I enjoyed it a lot.&lt;/li&gt;
&lt;li&gt;We did a very fun closing panel that was basically just six geeks disagreeing about lots of stuff. I hope everyone else enjoyed it as much as the panel members.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Conclusion: Øredev was a great conference, I was honored to get the chance to speak there and I’ll definitely try to go back next year.&lt;/p&gt;</description>
	<pubDate>Mon, 09 Nov 2009 11:06:42 +0000</pubDate>
<feedburner:origLink>http://olabini.com/blog/2009/11/a-week-at-oredev/</feedburner:origLink></item>
<item>
	<title>Joe Poon: The Last Mile</title>
	<guid isPermaLink="false">http://joepoon.com/blog/?p=108</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/Ghwy334ew4c/</link>
	<description>&lt;p&gt;&lt;a href="http://joepoon.com/blog/wp-content/uploads/2009/11/thelastmile.png"&gt;&lt;img src="http://joepoon.com/blog/wp-content/uploads/2009/11/thelastmile.png" style="margin-left: 3px; margin-right: 3px;" title="The Last Mile" height="210" width="316" alt="" class="size-full wp-image-132 alignleft"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Often the most painful and time consuming part of a software project is the Last Mile, getting it deployed and working in production.   Why is this the case?  To understand this, it is useful to look at the underlying issues such as not having decent source control, lack of automated tests, excessive branching (and eventual merging), dedicated teams and infrequent releases.  These impede our productivity on a daily basis and when left unresolved, become magnified during the Last Mile.&lt;/p&gt;
&lt;p&gt;Without shortening the Last Mile, our deployments are delayed and unpredictable events.  As a result, we are unable to quickly respond to changing business needs.&lt;/p&gt;
&lt;p&gt;So how do we shorten the Last Mile? Enter &lt;a href="http://martinfowler.com/articles/continuousIntegration.html"&gt;continuous integration&lt;/a&gt;.  The beauty of continuous integration is that it is the cornerstone for resolving these issues - it forces us to get source control under control, brings visibility to the health of our code base, challenges us to think of multiple environments and configurations and encourages us to automate repetitive tasks.  True to it’s name, it encourages us to integrate early and often. With CI, we’re already resolving integration issues from day 1 thereby making deployment to production thankfully, a non-event.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://tgould.blogspot.com/"&gt;Troy Gould&lt;/a&gt; and I presented The Last Mile at the &lt;a href="http://agilevancouver.ca/"&gt;Agile Vancouver&lt;/a&gt; 2009 Conference this week.  The presentation looks at the problems faced by teams trying to get software released, recommends good CI practices, introduces build pipelining with &lt;a href="http://studios.thoughtworks.com/cruise-release-management"&gt;Cruise&lt;/a&gt; as an overall structure to manage the build-deploy-test-release process and encourages us not to stop with CI as a build server, but leverage it to automate deployments to environments including production.  Thanks to those who attended.  It was exciting to see all those actively using CI on their projects.  The slides can be downloaded &lt;a href="http://joepoon.com/files/TheLastMile.pdf"&gt;here&lt;/a&gt; (17MB).&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href="http://exortech.com"&gt;Owen Rogers&lt;/a&gt; and the team of organizers for an excellent event and lining up a great set of speakers including &lt;a href="http://www.domainlanguage.com/"&gt;Eric Evans&lt;/a&gt;, &lt;a href="http://www.michaelfeathers.com/"&gt;Michael Feathers&lt;/a&gt; and &lt;a href="http://martinfowler.com/"&gt;Martin Fowler&lt;/a&gt;.&lt;/p&gt;</description>
	<pubDate>Mon, 09 Nov 2009 05:47:19 +0000</pubDate>
<feedburner:origLink>http://joepoon.com/blog/2009/11/08/the-last-mile/</feedburner:origLink></item>
<item>
	<title>James Crisp: Presentation Zen by Garr Reynolds</title>
	<guid isPermaLink="false">http://jamescrisp.org/2009/11/09/presentation-zen-by-garr-reynolds/</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/Vox1c9n26jY/</link>
	<description>&lt;p&gt;&lt;a href="http://jamescrisp.org/wordpress/wp-content/uploads/2009/11/presentationzen.jpg" title="presentationzen.jpg"&gt;&lt;img src="http://jamescrisp.org/wordpress/wp-content/uploads/2009/11/presentationzen.thumbnail.jpg" alt="presentationzen.jpg" style="float: left; margin-right: 5px;"&gt;&lt;/img&gt;&lt;/a&gt;After being impressed by &lt;a href="http://www.presentationzen.com/"&gt;Garr Reynolds&lt;/a&gt; speaking in Sydney a year or so ago, I've been keen to check out his &lt;a href="http://www.amazon.com/Presentation-Zen-Simple-Design-Delivery/dp/0321525655/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1257723978&amp;amp;sr=8-1"&gt;Presentation Zen&lt;/a&gt; book. It is an enlightening read, especially if you have never studied art or graphics design. The book is a little over 200 pages long, with many illustrations and a impressive, clean layout (no surprise there!).&lt;/p&gt;
&lt;p&gt;Near the start of the book, Garr talks about creativity requiring an open mind (child like) and a willingness to be wrong, and to experiment. He recommends exercising restraint, and focusing on simplicity, clarity and brevity. He starts presentations brainstorming using pen and paper, whiteboards or post-its rather than in front of the computer (personally I often use story cards as you can jot slide outlines on them, group, and shift the order around). He recommends grouping the ideas, and identifying the core message and sticking with that message throughout the whole presentation.&lt;/p&gt;
&lt;p&gt;Garr highlights the importance of taking the time to slow down and really think about what to put in the presentation. He suggests that you keep two important questions in mind: "What's your point?" (what one thing do you want the audience to remember), and "Why does it matter?" (put yourself in the audiences' shoes). If bits of your content don't aid in answering these questions, "when in doubt, cut it out"! Garr also suggests an "Elevator test" - can you make your pitch in 30-45 seconds? A structure that works well is starting with an introduction which explains the issue (the pain) and the core message. Then something like 3 parts that support your assertions or solve the pain (sounds a bit like &lt;a href="http://www.amazon.com/Solution-Selling-Creating-Difficult-Markets/dp/0786303158/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1257727513&amp;amp;sr=8-1"&gt;Bosworth's Solution Selling&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;"Amplification through simplification" is central to Garr's design approach. He advocates lots of empty space to highlight just one or a few important elements on a slide. "Simplicity can be obtained through the careful reduction of the non-essential" and decreasing the signal vs noise ratio of the slides. Garr is a big fan of using images on slides with just a few words. The aim is to make slides which have strong, memorable impact, and enhance the presenter's spoken words. He also highlights the importance of having the audience know where to look. Eg, simplicity plus images leading the eye to the right spot (eg, people in images on the slide look towards the words on the slide). Garr is a big fan of using quotes to support his points.&lt;/p&gt;
&lt;p&gt;Garr suggests a mix of symmetrical and asymmetrical slides. Symmetrical are more formal and static, where as asymmetrical slides are often more dynamic and interesting and activate empty space. He also suggests using a grid, such as the &lt;a href="http://en.wikipedia.org/wiki/Rule_of_thirds"&gt;rule of thirds&lt;/a&gt; (2 horizontal and 2 vertical lines providing a grid of 9 equally sized boxes), with the main subject placed on one of the crossing points of the lines. Contrast (using colour, shape, space, etc) can be used to make an element stand out and helps the viewer "get" the point of the design quickly. Repetition can be used (eg, text on each slide in an image of a post-it) to provide a professional and unified look. Use proximity to group related objects.&lt;/p&gt;
&lt;p&gt;Although Garr doesn't talk about it explicity, his sample slides tend to make use of clever typography. Often lower case text, with most important part in a bigger font. A mix of colours and sizes and styles and sometimes rotations to add interest to the slides. Generally sans-serif fonts.&lt;/p&gt;
&lt;p&gt;On presenting itself, Garr says you should be completely present - enthusiastic and completely focused on presentation that you are giving, lost in the moment. Nothing else. Although you may make mistakes, don't dwell on them. Practice like mad to become confident and appear easy and natural for the presentation. However, remain flexible, aware and open to possibilities as they arise (being "in the moment").&lt;/p&gt;
&lt;p&gt;Near the end of the book, Garr says: "It's not about us [the presenter], it's about them. And about the message.". He also suggests that shorter is better, leave the audience wanting more, not overloaded (as per Japanese proverb "eat until 80% full"). On delivery, Garr suggests standing front and centre, leaving the lights on and advancing slides with a remote.&lt;/p&gt;
&lt;p&gt;Garr's points are much more clearly illustrated using images in the book. I would recommend Presentation Zen to anyone who is interested in making more visually inspiring and interesting presentations. &lt;/p&gt;</description>
	<pubDate>Mon, 09 Nov 2009 04:25:23 +0000</pubDate>
<feedburner:origLink>http://jamescrisp.org/2009/11/09/presentation-zen-by-garr-reynolds/</feedburner:origLink></item>
<item>
	<title>Ye Zheng: 我们很忙</title>
	<guid isPermaLink="false">http://dreamhead.blogbus.com/logs/50687566.html</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/2fXSw2TGAgs/50687566.html</link>
	<description>&lt;p&gt;软件开发似乎就应该是忙碌的，加班似乎也应该是常态。我听到最为痛心的一个说法是，每天都在加班，忙得连洗衣服的时间都没有。也是因为忙，忙得有没有时间学习、没有时间思考。所有一切都是因为忙。&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;但是，我们都是怎么忙的呢？不妨看一些细节。&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;软件开发中，最重要的过程应该是编码，但真正的编码有多长时间呢？在一个采用传统开发方式的团队中，会有一个最后集成阶段。因为前期做的验证不够充分，所以，要给后面留下很长的时间，用来做集成和测试，更有甚者，这个时间要比“开发”时间还长。这里的“开发”阶段只是在纯粹的编码。就这样，在计划中，很大的一段时间被砍掉了。&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;即便是在“开发”阶段，就真正能坐在那里好好写代码吗？未必。在大企业里面，最浪费时间的是什么？开会。人多，沟通不畅，开会成了“自然”的选择，而且，往往是人越多，会就越多。事实上，很多企业的会都是非常低效，一开会就发散，通常一个会一两个小时就进去了。在《&lt;a href="http://dreamhead.blogbus.com/logs/46834395.html" target="_blank"&gt;做好一件事&lt;/a&gt;》中还提到矩阵式管理也会让人无法好好写代码。就这样，在团队开发中，又有一段时间被消耗掉了。&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;即便真正开始写代码，又是怎么做的呢？对于历史悠久的产品而言，程序员需要面对大量的遗留代码，编译一次代码，都要用很长时间，这意味着，消除编译错误这样原本应该很简单的事情都要消耗大量的时间。于是，经常可以看到一个个程序员面无表情的在那里等待编译。遗留代码，通常也意味着欠了一屁股的技术债务，也就是说，为一个功能要遍地开花的改许多代码，这也很耗时。对于不编写单元测试的程序员，常用的验证手段就是调试器，因为人的参与，这个过程不能自动化，很是缓慢。好容易到了该提交代码了，因为文件很大，出现冲突的几率也增加了，处理冲突也是耗时的事。在个人开发中，时间就在不知不觉中流逝。&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;我们很忙，因为忙而认为一切都是理所当然的。正如上面所列，很多时间实际上是在一环扣一环的低效中无谓消耗了，所以，每天不得不加班，让自己看上去很忙，以此换回内心的“安宁”。&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;我们真的很忙吗？&lt;/p&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;div class="sysmsg"&gt;&lt;b&gt;&lt;a href="http://www.blogbus.com" target="_blank"&gt;博客大巴，你的个人传媒早班车&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;</description>
	<pubDate>Sun, 08 Nov 2009 15:52:32 +0000</pubDate>
<feedburner:origLink>http://dreamhead.blogbus.com/logs/50687566.html</feedburner:origLink></item>
<item>
	<title>Mark Needham: Coding: The agent noun class</title>
	<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=1803</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/vLliToQ0pz4/</link>
	<description>&lt;p&gt;I refer quite frequently to a post written by my colleague Peter Gillard Moss where he describes the &lt;a href="http://jupitermoonbeam.blogspot.com/2008/09/agent-nouns-are-code-smells.html"&gt;agent noun code smell for class names&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;An agent noun is &lt;a href="http://en.wikipedia.org/wiki/Agent_noun"&gt;defined by Wikipedia&lt;/a&gt; as:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
In linguistics, an agent noun (or nomen agentis) is a word that is derived from another word denoting an action, and that identifies an entity that does that action.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Some typical examples of this are classes which end in the name 'Manager', 'Retriever', 'Helper' or even 'Controller' &lt;a href="http://www.lixo.org/archives/2008/09/12/opportunity-makes-the-thief/"&gt;as Carlos points out&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It's often the case that these classes better describe a method which belongs on another object and I quite like Peter's idea that agent nouns are useful for describing the &lt;a href="http://www.markhneedham.com/blog/2009/10/18/coding-role-based-interfaces/"&gt;roles that our objects carry out&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;We came across an interesting problem related to this a while ago where we wanted to calculate the age of a given customer and then send that data to another web page where it would be displayed.&lt;/p&gt;
&lt;p&gt;The date of birth was an attribute on the 'Customer' object and we didn't need any of the other attributes of a customer on this web page so my first thought was that we needed an 'AgeCalculator' class.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="csharp"&gt;&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;class&lt;/span&gt; AgeCalculator 
&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
	&lt;span style="color: #0600FF;"&gt;private&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;readonly&lt;/span&gt; IClock clock&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
 
	&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; AgeCalculator&lt;span style="color: #000000;"&gt;(&lt;/span&gt;IClock clock&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
		&lt;span style="color: #0600FF;"&gt;this&lt;/span&gt;.&lt;span style="color: #0000FF;"&gt;clock&lt;/span&gt; &lt;span style="color: #008000;"&gt;=&lt;/span&gt; clock&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
 
	&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;int&lt;/span&gt; CalculateAge&lt;span style="color: #000000;"&gt;(&lt;/span&gt;DateTime dataOfBirth&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
		&lt;span style="color: #008080; font-style: italic;"&gt;// do some calculation with clock &amp;amp; date of birth here&lt;/span&gt;
	&lt;span style="color: #000000;"&gt;}&lt;/span&gt;
&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;


&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="csharp"&gt;&lt;span style="color: #0600FF;"&gt;public&lt;/span&gt; &lt;span style="color: #0600FF;"&gt;void&lt;/span&gt; SomeMethod&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;
&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
	var age &lt;span style="color: #008000;"&gt;=&lt;/span&gt; &lt;span style="color: #008000;"&gt;new&lt;/span&gt; AgeCalculator&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #008000;"&gt;new&lt;/span&gt; Clock&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;.&lt;span style="color: #0000FF;"&gt;CalculateAge&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;customer.&lt;span style="color: #0000FF;"&gt;DateOfBirth&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;
	&lt;span style="color: #008080; font-style: italic;"&gt;// and so on &lt;/span&gt;
&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This approach worked quite well as it allowed us to easily test the age calculation logic in isolation and we could then pass on the age returned to the web page.&lt;/p&gt;
&lt;p&gt;The thing I didn't like about this solution is that it seems a lot like an agent noun class. &lt;/p&gt;
&lt;p&gt;The giveaway in this case is that the method name is just a variation on the class name. This suggests that this behaviour belongs on another object instead.&lt;/p&gt;
&lt;p&gt;It's not as object oriented as it could be but it doesn't seem as bad as some of the other examples such as classes ending in 'Manager' since this object is only solving one problem and we do have calculators in real life.&lt;/p&gt;
&lt;p&gt;Some colleagues suggested that perhaps age should be an attribute on the customer which does seem to be a better place for this logic to reside.&lt;/p&gt;
&lt;p&gt;On the other hand age isn't used anywhere else in the application and we don't need any of the other attributes of customer as I mentioned earlier.&lt;/p&gt;
&lt;p&gt;I'm not sure what the 'right' solution is but there seem to be a few different potential approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Should age be an attribute of the customer? There could be a tiny type 'Age' which does the above logic.&lt;/li&gt;
&lt;li&gt;Should we have a role/interface 'ICalculateAges' which the customer implements?&lt;/li&gt;
&lt;li&gt;Should we just keep the 'AgeCalculator'?&lt;/li&gt;
&lt;li&gt;Is there some other solution that I'm not seeing?!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;–&lt;/p&gt;
&lt;p&gt;In reality after we'd discussed all these alternatives it turned out that the requirement was slightly wrong and that we actually needed to send down the date of birth and not the age. &lt;/p&gt;
&lt;p&gt;I still think it's an interesting problem though and one that I'm bound to come across again!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/MarkNeedham/~4/WT5Gn_SwPG8" height="1" width="1"&gt;&lt;/img&gt;</description>
	<pubDate>Sun, 08 Nov 2009 10:44:18 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/MarkNeedham/~3/WT5Gn_SwPG8/</feedburner:origLink></item>
<item>
	<title>Simon Brunning: Links for 2009-11-07 [del.icio.us]</title>
	<guid isPermaLink="false">http://del.icio.us/brunns#2009-11-07</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/8PVXokQpxFM/brunns</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://research.microsoft.com/en-us/news/features/nagappan-100609.aspx"&gt;Exploding Software-Engineering Myths - Microsoft Research&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://openofficemouse.com/pr110609.html"&gt;OpenOfficeMouse&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
This *can't* be real, surely?&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Sun, 08 Nov 2009 08:00:00 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/SmallValuesOfCool/~3/58dZLfXqW_o/brunns</feedburner:origLink></item>
<item>
	<title>Mark Needham: Knowing when to persevere and when to change approach</title>
	<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=1797</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/GGSWI9GBtdA/</link>
	<description>&lt;p&gt;It strikes me that one of the most important skills to develop in software development is knowing when to keep going with an approach to a problem and when we should stop and try something else.&lt;/p&gt;
&lt;p&gt;This situation doesn't always happen because if we have two people available and realise before we start on the task that there is some doubt as to which solution is the most appropriate then we can adopt a &lt;a href="http://www.markhneedham.com/blog/2009/09/19/set-based-concurrent-engineering-a-simple-example/"&gt;set based approach&lt;/a&gt; whereby we try out multiple potential solutions in parallel.&lt;/p&gt;
&lt;p&gt;However I've found that there are times when we might think that one solution is much better than the alternatives and we will start working on that and discard the alternatives for the moment.&lt;/p&gt;
&lt;p&gt;Frequently the approach we choose will solve our problem but on other occasions we can end up getting a bit bogged down when it doesn't work out as expected.&lt;/p&gt;
&lt;p&gt;At this stage I often find that my instinct is to try and solve these problems and while I think this is certainly a valid approach it's also very easy to end up &lt;a href="http://www.markhneedham.com/blog/2008/10/25/dont-shave-the-yak-ask-why-are-we-doing-this/"&gt;shaving the yak&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This seems to happen much more frequently when working alone and even when we're getting feedback which suggests that what we're trying isn't working we can be reluctant to back track.&lt;/p&gt;
&lt;p&gt;I think there is some pride involved as I frequently find myself really wanting to make the current approach work as I believe that a better developer than myself would be able to do so. &lt;/p&gt;
&lt;p&gt;Sometimes that is the case but more often than not when I work through the problem with a colleague their suggestion is to try another approach rather than continuing to struggle with the current one.&lt;/p&gt;
&lt;p&gt;It doesn't make a lot of sense to spend all our time going down one avenue when our goal is solve a particular problem and the solution is a means to that end.&lt;/p&gt;
&lt;p&gt;When discussing this with &lt;a href="http://pilchardfriendly.wordpress.com/"&gt;Nick&lt;/a&gt; he pointed out that we also need to recognise when we should persevere with the approach.&lt;/p&gt;
&lt;p&gt;One way to avoid too much yak shaving is to set a &lt;a href="http://en.wikipedia.org/wiki/Timeboxing"&gt;timebox&lt;/a&gt; by when we should either have a better idea of whether we are going to be able to solve the problem with this solution or if we need to consider an alternative.&lt;/p&gt;
&lt;p&gt;If there's some light at the end of the tunnel with an approach after this period then I would be inclined to keep on going but it's sometimes difficult to tell how close we actually are and how much is wishful thinking!&lt;/p&gt;
&lt;p&gt;I still sometimes find myself struggling to decide whether to keep going or change direction so it'd be interesting to know if anyone has ideas around doing so more effectively.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/MarkNeedham/~4/J6lCw6dpv_s" height="1" width="1"&gt;&lt;/img&gt;</description>
	<pubDate>Sat, 07 Nov 2009 23:57:41 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/MarkNeedham/~3/J6lCw6dpv_s/</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: Looking forward to DevLearn 2009</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-7237088950140109237</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/R5geJioSnCU/looking-forward-to-devlearn-2009.html</link>
	<description>&lt;center&gt;&lt;a href="http://www.elearningguild.com/content.cfm?selection=doc.1275"&gt;&lt;img src="http://www.elearningguild.com/assets/images/devlearn09/icons/DL09badge-Attending.png" height="95" width="250"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/center&gt;&lt;br&gt;&lt;/br&gt;If we've ever corresponded online, I'd love to have the opportunity to put a face to your name. Please do get in touch and say hi -- I'm looking forward to networking with a lot of learning professionals at the conference. See you there!&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-7237088950140109237?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Sat, 07 Nov 2009 23:42:40 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/VdjR6k2ss3A/looking-forward-to-devlearn-2009.html</feedburner:origLink></item>
<item>
	<title>Sumeet Moghe: Put your learners on a diet - consider a pull-based learning approach</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-8396317.post-5120839371038667761</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/-HV_QXAeQb4/put-your-learners-on-diet-consider-pull.html</link>
	<description>&lt;a href="http://farm4.static.flickr.com/3409/3211821742_271da2177d.jpg"&gt;&lt;img src="http://farm4.static.flickr.com/3409/3211821742_271da2177d.jpg" alt="" border="0" style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; cursor: hand; width: 500px; height: 375px;"&gt;&lt;/img&gt;&lt;/a&gt;Have you ever had a time when you got slammed in the face with a huge plate of food which you just couldn't say no to? I have. Picture the above meal -- for some it might just be the tastiest thing they could imagine. For me, while I find it difficult to say no sometimes and even if I only want a little, I have to labour through the entire meal. I just got off a five hour flight to Hong Kong, and I've had a bit of an epiphany. Let me tell you the story first. This flight left Bangalore at about 2:35 AM -- a time at which I'm usually fast asleep. So what I really wanted on this flight was some sleep. That said, airlines have a strange sense of hospitality so at about 3:30 AM they made me put my seat back upright, turned on the lights and gave me some food to eat. Well I can't say no to food, so I ate. They then kept the lights on at full-blast; don't know why, but they did. If that snack wasn't enough, at about 6:30 AM they shook me up and asked, "Vegetarian or Non-vegetarian". My instinctive response is "Non-vegetarian" and well I got what I asked for while being half asleep, but really I didn't need a big breakfast with beans, tomatoes, sausages, an omelette, potatoes, yoghurt, fruits, cheesy bread and juice. I really just wanted some sleep. A part of me wondered if it was ever going to be possible for me to tailor my flight experience for the next several years that I travel economy! And then, all of a sudden I thought about training (like I always do!).&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;h3&gt;Most training experiences push learning to the learner&lt;/h3&gt;&lt;a href="http://dl.dropbox.com/u/478762/pushvpull.002.png"&gt;&lt;img src="http://dl.dropbox.com/u/478762/pushvpull.002.png" alt="" border="0" style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; cursor: hand; width: 560px; height: 412px;"&gt;&lt;/img&gt;&lt;/a&gt;Regardless of our good intentions, many of the courses we design tend to take a whole bunch of learning objectives which we then push onto the learner. We keep asking ourselves the question of whether something needs to go into a course and then we say, &lt;em&gt;"But they really need to know this..."&lt;/em&gt; and we slam that topic right into the training. While some learners enjoy it and others endure it, we need to ask ourselves if this is really effective. Research proves that human brains work very sensibly in these situations -- we stay conscious only about the pieces of knowledge or the skills that we will need/use on our immediate work. The rest slips into the subconscious and we incubate those bits of information until we need it at a later time. &lt;a href="http://brainrules.net/"&gt;John Medina's Brain Rules&lt;/a&gt;, explain these phenomena in great detail. So if people are only going to retain what they will use, why contaminate that message with the surrounding &lt;em&gt;nice-to-have&lt;/em&gt; stuff?&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;h3&gt;Learners need to be self aware&lt;/h3&gt;&lt;a href="http://dl.dropbox.com/u/478762/pushvpull.003.png"&gt;&lt;img src="http://dl.dropbox.com/u/478762/pushvpull.003.png" alt="" border="0" style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; cursor: hand; width: 560px; height: 518px;"&gt;&lt;/img&gt;&lt;/a&gt;People learn from experience and most learning sinks in, on the job. People learn from feedback and feedback comes not only from peers and coaches, it also comes from your environment. When you keep attempting something and get a result that you didn't expect, you're getting some feedback. The key is that as people progress on the job, they get feedback from various sources and become more and more self-aware about where they are and where they'd like to be. A safe environment to fail fast and learn from mistakes is critical to this self-awareness. So I often think that while training is important, its more important for organisations to provide a safe environment that's conducive to learning. Only then can you develop people that are truly in control of their development and have the awareness they need to succeed.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;&lt;h3&gt;Self aware learners can pull the learning they need&lt;/h3&gt;&lt;a href="http://dl.dropbox.com/u/478762/pushvpull.001.png"&gt;&lt;img src="http://dl.dropbox.com/u/478762/pushvpull.001.png" alt="" border="0" style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; cursor: hand; width: 560px; height: 247px;"&gt;&lt;/img&gt;&lt;/a&gt;Once you're self aware, you automatically know what resources you need to learn. The key is that different people learn differently. Some people learn by reading a book, others by attending a course, a lot of people can learn effectively online and there are others who learn by networking and socialising with people. The key to being a learning organisation is in providing these learning opportunities throughout someone's career. There are many ways to create these opportunities. Here are some I can think of:&lt;ul&gt;&lt;li&gt;Design your instructor led courses to be no more than 90 minutes each with a targeted set of objectives for each 90 minute chunk. This way, you increase your flexibility to run them on-demand&lt;/li&gt;&lt;li&gt;Design your elearning to be in the form of small &lt;em&gt;coursels&lt;/em&gt; (like morsels in case of food). Think of bite-sized chunks no longer than 10 minutes. Adopt a how-to approach.&lt;/li&gt;&lt;li&gt; Invest in &lt;a href="http://en.wikipedia.org/wiki/Enterprise_social_software"&gt;Enterprise Social Software&lt;/a&gt; for your firm, so that people can crowdsource learning. After all, most learning happens by talking to the guy that sits beside you, or over that cup of coffee. Most importantly this opens up opportunities for your learners to network with people they never knew&lt;/li&gt;&lt;li&gt; Facilitate informal events, like &lt;a href="http://www.seattlewireless.net/HackNight"&gt;Hack Nights&lt;/a&gt;, Lunch and Learns (people bring in food and sit in a session over lunch), &lt;a href="http://www.google.co.in/url?sa=t&amp;amp;source=web&amp;amp;ct=res&amp;amp;cd=1&amp;amp;ved=0CAgQFjAA&amp;amp;url=http%3A%2F%2Fwww.pecha-kucha.org%2F&amp;amp;rct=j&amp;amp;q=pecha+kucha&amp;amp;ei=Dff0SpKVBqCO6APo2vwH&amp;amp;usg=AFQjCNE7kQ00wgJuYrJwKan9sbrLyn2ZJw"&gt;Pecha-Kucha&lt;/a&gt; nights and &lt;a href="http://ignite.oreilly.com"&gt;Ignite&lt;/a&gt; evenings.&lt;/li&gt;&lt;li&gt; Institute other forms of support such as a book budget where people have the opportunity to spend money on something they feel can help their learning.&lt;/li&gt;&lt;/ul&gt; &lt;hr&gt;&lt;/hr&gt;I'm sure there are dozens of other, non-intrusive ways to create opportunities for continuous learning. What has your experience been with things such as this? Feel free to share your thoughts liberally in the &lt;a href="https://www.blogger.com/comment.g?blogID=8396317&amp;amp;postID=5120839371038667761"&gt;comments section of the post&lt;/a&gt; and if you'd like to, &lt;a href="mailto:sumeet@sumeetmoghe.com"&gt;please write to me&lt;/a&gt;.&lt;br&gt;&lt;/br&gt;&lt;span style="font-style: italic;"&gt;&lt;br&gt;&lt;/br&gt;(Photograph in this post taken from &lt;a href="http://www.flickr.com/photos/30415776@N04/"&gt;cocomo7's Flickr stream&lt;/a&gt;)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;© Sumeet Moghe, 2009&lt;img src="https://blogger.googleusercontent.com/tracker/8396317-5120839371038667761?l=cipher-quaker.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Sat, 07 Nov 2009 22:33:18 +0000</pubDate>
	<author>noreply@blogger.com (Sumeet Moghe)</author>
<feedburner:origLink>http://feedproxy.google.com/~r/blogspot/sawZ/~3/Vq-CcKPATh8/put-your-learners-on-diet-consider-pull.html</feedburner:origLink></item>
<item>
	<title>Steven List: With Blame Goes Guilt</title>
	<guid isPermaLink="false">http://www.stevenlist.com/blog/2009/11/07/withblamegoesguilt/</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/S-FMS_iWyFA/</link>
	<description>&lt;p&gt;I was talking to a colleague last night about my thoughts around &lt;a href="http://www.stevenlist.com/blog/2009/10/30/cultureofblame/" target="_blank"&gt;A Culture of Blame&lt;/a&gt;. He was sharing with me one of the tactics used by management, and it occurred to me that it’s hard to live in a &lt;a href="http://www.stevenlist.com/blog/tag/culture/" class="st_tag internal_tag" rel="tag" title="Posts tagged with culture"&gt;culture&lt;/a&gt; of &lt;a href="http://www.stevenlist.com/blog/tag/blame/" class="st_tag internal_tag" rel="tag" title="Posts tagged with blame"&gt;blame&lt;/a&gt; without also having &lt;a href="http://www.stevenlist.com/blog/tag/blame/" class="st_tag internal_tag" rel="tag" title="Posts tagged with blame"&gt;blame&lt;/a&gt;’s counterpart, guilt.&lt;/p&gt;
&lt;p&gt;“We’ve made a commitment to our customer, and we must fulfill that commitment.” This frequently means “I made a commitment to our customer, and YOU must fulfill that commitment (or YOU will suffer).”&lt;/p&gt;
&lt;p&gt;Poor managers frequently combine &lt;a href="http://www.stevenlist.com/blog/tag/blame/" class="st_tag internal_tag" rel="tag" title="Posts tagged with blame"&gt;blame&lt;/a&gt; and guilt as their two weapons of destruction. Rather than think of positive ways to motivate people, they undermine and discourage, somehow believing that this will produce better results.&lt;/p&gt;
&lt;p&gt;Research and anecdotal evidence reveal that reward and positive motivation work far, far better than punishment and &lt;a href="http://www.stevenlist.com/blog/tag/negative/" class="st_tag internal_tag" rel="tag" title="Posts tagged with negative"&gt;negative&lt;/a&gt; motivation. And yet, there we are.&lt;/p&gt;
&lt;p&gt;One of the many things I love about &lt;a href="http://www.stevenlist.com/blog/tag/agile/" class="st_tag internal_tag" rel="tag" title="Posts tagged with Agile"&gt;Agile&lt;/a&gt; teams is that we move away from &lt;a href="http://www.stevenlist.com/blog/tag/blame/" class="st_tag internal_tag" rel="tag" title="Posts tagged with blame"&gt;blame&lt;/a&gt; and guilt to collaboration, support, respect, and motivation.&lt;/p&gt;
&lt;div class="zemanta-pixie"&gt;&lt;img src="http://img.zemanta.com/pixy.gif?x-id=50d7fae6-3247-8374-a48d-9223a57abe72" alt="" class="zemanta-pixie-img"&gt;&lt;/img&gt;&lt;/div&gt;
&lt;p align="left"&gt;&lt;a href="http://twitter.com/home/?status=With+Blame+Goes+Guilt+http://yi88p.th8.us" class="tt" title="Post to Twitter"&gt;&lt;img src="http://www.stevenlist.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" class="nothumb"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://twitter.com/home/?status=With+Blame+Goes+Guilt+http://yi88p.th8.us" class="tt" title="Post to Twitter"&gt;Tweet This Post&lt;/a&gt;&lt;/p&gt;&lt;a href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.stevenlist.com%2Fblog%2F2009%2F11%2F07%2Fwithblamegoesguilt%2F&amp;amp;linkname=With%20Blame%20Goes%20Guilt" class="a2a_dd addtoany_share_save"&gt;&lt;img src="http://www.stevenlist.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" alt="Share/Bookmark" height="16" width="171"&gt;&lt;/img&gt;&lt;/a&gt;
	&lt;h4&gt;Related posts&lt;/h4&gt;
	&lt;ul class="st-related-posts"&gt;
	&lt;li&gt;&lt;a href="http://www.stevenlist.com/blog/2009/02/03/whose-fault/" title="Whose fault (February 3, 2009)"&gt;Whose fault&lt;/a&gt; (2)&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.stevenlist.com/blog/2009/06/10/heres-your-gun-theres-your-foot/" title="Here’s your gun, there’s your foot (June 10, 2009)"&gt;Here’s your gun, there’s your foot&lt;/a&gt; (5)&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.stevenlist.com/blog/2009/10/30/cultureofblame/" title="A Culture of Blame (October 30, 2009)"&gt;A Culture of Blame&lt;/a&gt; (9)&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.stevenlist.com/blog/2009/06/11/yo-pass-the-potatoes/" title="Yo! Pass the potatoes! (June 11, 2009)"&gt;Yo! Pass the potatoes!&lt;/a&gt; (3)&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.stevenlist.com/blog/2008/02/04/whats-in-it-for-them/" title="What’s in it for them? (February 4, 2008)"&gt;What’s in it for them?&lt;/a&gt; (0)&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Sat, 07 Nov 2009 20:18:29 +0000</pubDate>
<feedburner:origLink>http://www.stevenlist.com/blog/2009/11/07/withblamegoesguilt/</feedburner:origLink></item>
<item>
	<title>Liang Qiao: where is the first step in Lean thinking</title>
	<guid isPermaLink="false">http://blog.csdn.net/tony1130/archive/2009/11/07/4783654.aspx</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/YGVM3EJAl1M/4783654.aspx</link>
	<description>Value-creating work.Activities adding directly to the value of the product as determined bythe customer. (Manufacturing examples are painting the product oradding parts during assembly.) A simple test is to ask whethercustomers would mind if this work was not done but their product stillperformed properly. If they would mind, it is value creating. Forexample, almost all customers expect their products to be painted withall the parts assembled, so these steps are value crea&lt;img src="http://www1.feedsky.com/t1/293425578/tony1130/csdn.net/s.gif?r=http://blog.csdn.net/tony1130/archive/2009/11/07/4783654.aspx" height="0" border="0" width="0"&gt;&lt;/img&gt;&lt;p class="fswww1"&gt;&lt;a href="http://www1.feedsky.com/r/l/csdn.net/tony1130/293425578/art01.html" target="_blank"&gt;&lt;img src="http://www1.feedsky.com/r/i/csdn.net/tony1130/293425578/art01.gif" border="0" ismap="ismap"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Sat, 07 Nov 2009 13:31:00 +0000</pubDate>
<feedburner:origLink>http://blog.csdn.net/tony1130/archive/2009/11/07/4783654.aspx</feedburner:origLink></item>
<item>
	<title>Kai Hu: 5个为什么</title>
	<guid isPermaLink="false">http://www.iamhukai.com/?p=125</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/BT1I1_uDDgk/</link>
	<description>&lt;p&gt;就在前两天，我们一起合作的团队某PL在本地（而不是在专门的服务器上）手工编译大包时，忘记了清理几个文件夹，导致编出的大包不可用，发布组花了一天的时间才发现原因是编译引起的。&lt;/p&gt;
&lt;p&gt;事实上，在持续集成服务器上，有一个项目是专门用于生成大包的，但是这个PL却宁可去手动编译，我本想给他再说教一遍自动化是如何的好，可重复，效率高，但话在出口时变成了：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;span style="color: #0000ff;"&gt;你干嘛不在持续集成服务器上点一下呢？ 手工编多麻烦啊，还得改配置。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;我也知道啊，但是不能点啊，我看不见那个按钮&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #0000ff;"&gt;你为什么会看不见那个按钮呢？把页面打开我看看&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;原来是没有权限啊，你为什么不让管持续集成服务器的人给你开个权限呢？&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #0000ff;"&gt;他不给开啊&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;我去问问。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;于是我找到了负责持续集成服务器人：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;嘿，你为什么不给XX开权限呢？他在负责生成大包呢。&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #0000ff;"&gt;如果给了他权限，几个人都一起点上面的按钮怎么办呢？&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #0000ff;"&gt;&lt;span style="color: #000000;"&gt;不会的，你看（演示给他看），服务器自己会处理的&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;你看，原来真正的原因在这里，负责持续集成服务器的人不了解持续集成服务器的工作机制，对未知的恐惧让他不相信任何人，打消了他的顾虑，我又回到之前犯了错误的PL那里，&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;最后一个问题，就算手工编译，为什么不在服务器上进行呢？你自己的机器多慢啊&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #0000ff;"&gt;服务器是Windows 2003，允许多人登录，我如果在上面手工编译，可能会有别人也在上面编译的，协调机会出问题的，而且还有别人在上面调试脚本，我可能会影响他们的。&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;span style="color: #0000ff;"&gt;&lt;span style="color: #000000;"&gt;于是我和他一起重新配置了2003服务器，只允许同一时刻一个用户登录。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #0000ff;"&gt;&lt;span style="color: #000000;"&gt;并且我得到了下面的问题列表：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #0000ff;"&gt;&lt;span style="color: #000000;"&gt;为什么不能同时编译不同的项目呢？ 问题在哪儿？&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #0000ff;"&gt;&lt;span style="color: #000000;"&gt;为什么有人在服务器上调脚本呢？ 服务器不是工作机，他们面临的是什么问题？&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;…….&lt;/p&gt;
&lt;p&gt;还记得当初我们面对的问题么？&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;有人不去自动化的生成大包&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;我们解决了的是什么问题呢？&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;对持续集成服务器的功能不熟悉&lt;/p&gt;
&lt;p&gt;服务器的操作系统没有经过精心的配置&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;当我们不断的追问时，你会发现问题的真相在不断的浮出来，用眼睛观察问题，也不见得为实。亲爱的咨询师同事们，我建议你们也在自己的工具箱里面加上这个工具：  &lt;a href="http://en.wikipedia.org/wiki/5_Whys"&gt;5 Whys&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Sat, 07 Nov 2009 12:27:07 +0000</pubDate>
<feedburner:origLink>http://www.iamhukai.com/?p=125</feedburner:origLink></item>
<item>
	<title>Liang Qiao: 如何使用企业持续集成成熟度模型？</title>
	<guid isPermaLink="false">http://blog.csdn.net/tony1130/archive/2009/11/07/4783208.aspx</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/SFLb0YgYgEM/4783208.aspx</link>
	<description>所有团队在四个维度都达到统一的企业持续集成成熟度是很困难的。企业持续集成在不同的条件和状态下，应该考虑选择不同的方向来实现或加强。为了表明这一点，下面是一个企业的例子，提供了企业持续集成混合成熟度的解决方法。&lt;img src="http://www1.feedsky.com/t1/293387801/tony1130/csdn.net/s.gif?r=http://blog.csdn.net/tony1130/archive/2009/11/07/4783208.aspx" height="0" border="0" width="0"&gt;&lt;/img&gt;&lt;p class="fswww1"&gt;&lt;a href="http://www1.feedsky.com/r/l/csdn.net/tony1130/293387801/art01.html" target="_blank"&gt;&lt;img src="http://www1.feedsky.com/r/i/csdn.net/tony1130/293387801/art01.gif" border="0" ismap="ismap"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Sat, 07 Nov 2009 10:34:00 +0000</pubDate>
<feedburner:origLink>http://blog.csdn.net/tony1130/archive/2009/11/07/4783208.aspx</feedburner:origLink></item>
<item>
	<title>Liang Qiao: 企业持续集成成熟度模型简介之四——报告</title>
	<guid isPermaLink="false">http://blog.csdn.net/tony1130/archive/2009/11/07/4783116.aspx</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/EFPiJLI29yA/4783116.aspx</link>
	<description>持续集成工具一直以来就负责报告最近一次构建的状态。报告是持续集成的一个至关重要的元素。在企业持续集成中，报告应包含所做软件的相关质量和内容方面的信息，以及与企业持续集成过程有关的度量信息。没有报告的团队就象一个没有雷达的飞机在飞行。如果没有人看测试结果的话，所有的测试都是无用的。同样，很多数据如果没有被提取成可消化利用的信息的话，就很难使用，一样可以视为无用。越成熟团队的报告，其可视化程度越高，有用的信息也会越多。
很多工具在构建过程中都会产生报告。在一个团队中，如果某人利用一些工具来产生报告，并分析它，之后会根据它来做出行动的话，这个团队就已经是入门级成熟度了。&lt;img src="http://www1.feedsky.com/t1/293361395/tony1130/csdn.net/s.gif?r=http://blog.csdn.net/tony1130/archive/2009/11/07/4783116.aspx" height="0" border="0" width="0"&gt;&lt;/img&gt;&lt;p class="fswww1"&gt;&lt;a href="http://www1.feedsky.com/r/l/csdn.net/tony1130/293361395/art01.html" target="_blank"&gt;&lt;img src="http://www1.feedsky.com/r/i/csdn.net/tony1130/293361395/art01.gif" border="0" ismap="ismap"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Sat, 07 Nov 2009 09:46:00 +0000</pubDate>
<feedburner:origLink>http://blog.csdn.net/tony1130/archive/2009/11/07/4783116.aspx</feedburner:origLink></item>
<item>
	<title>Simon Brunning: Links for 2009-11-06 [del.icio.us]</title>
	<guid isPermaLink="false">http://del.icio.us/brunns#2009-11-06</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/SymaTzYoGnM/brunns</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.rhonabwy.com/wp/2009/11/04/setting-up-a-python-ci-server-with-hudson/"&gt;Setting up a Python CI server with Hudson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jacobian.org/writing/thank-you-rails/"&gt;Thank you, Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://neopythonic.blogspot.com/2009/11/python-in-scientific-world.html"&gt;Python in the Scientific World&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codethinked.com/post/2009/11/05/Ite28099s-Okay-To-Write-Unit-Tests.aspx"&gt;It’s Okay To Write Unit Tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Post/Redirect/Get"&gt;Post/Redirect/Get&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gitx.frim.nl/"&gt;GitX&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
GitX is a git GUI made for Mac OS X&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twittertim.es/brunns"&gt;The Twitter Times: brunns&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Sat, 07 Nov 2009 08:00:00 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/SmallValuesOfCool/~3/cXHfCpcKiGg/brunns</feedburner:origLink></item>
<item>
	<title>Patrick Kua: Fixing Notepad++ 5.5 Langs.xml</title>
	<guid isPermaLink="false">http://www.thekua.com/atwork/?p=781</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/y5ygI0U8up4/</link>
	<description>&lt;p&gt;&lt;img src="http://www.thekua.com/atwork/wp-content/uploads/2009/11/LangsXmlFailed.png" alt="LangsXml Failed to Load" style="float: right;"&gt;&lt;/img&gt;I upgraded to the latest version of &lt;a href="http://notepad-plus.sourceforge.net/uk/site.htm"&gt;Notepad++ (5.5)&lt;/a&gt; and noticed that I sometimes get some problems with a dialogue box that pops up, looking like the picture the right stating (Load Langs.xml failed!)&lt;/p&gt;
&lt;p&gt;Having a quick look at the installation directory, it looks like a &lt;code&gt;langs.xml&lt;/code&gt; file exists yet it has a 0KB size. I’m not sure what causes it yet (perhaps it’s if you kill the process mid-way using Task Manager) but all I did was take a copy of &lt;code&gt;langs.model.xml&lt;/code&gt; and rename the copy as &lt;code&gt;langs.xml&lt;/code&gt;. Fixes it all up!&lt;/p&gt;</description>
	<pubDate>Fri, 06 Nov 2009 18:25:02 +0000</pubDate>
<feedburner:origLink>http://www.thekua.com/atwork/2009/11/fixing-notepad-5-5-langs-xml/</feedburner:origLink></item>
<item>
	<title>Jie Xiong: Sponsor的价值所在</title>
	<guid isPermaLink="false">tag:gigix.thoughtworkers.org,2009-11-06:644</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/wMx9I_qiN-Y/value-of-sponsor</link>
	<description>&lt;p&gt;今儿给麦罗打电话的片段摘录…&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;我：俺们SVN server装Windows上，用个32位Apache做前端，那玩意有2G内存限制…&lt;/li&gt;
		&lt;li&gt;麦：一，用Windows做SVN server。二，代码库很大。三，很多人同时访问。&lt;/li&gt;
		&lt;li&gt;我：对头～～&lt;/li&gt;
		&lt;li&gt;麦：你在XX公司？&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;知音啊～～我又内牛满面了～～介个就是Sponsor的价值亚～～&lt;/p&gt;</description>
	<pubDate>Fri, 06 Nov 2009 14:38:10 +0000</pubDate>
<feedburner:origLink>http://gigix.thoughtworkers.org/2009/11/6/value-of-sponsor</feedburner:origLink></item>
<item>
	<title>Mark Needham: TDD: Useful when new on a project</title>
	<guid isPermaLink="false">http://www.markhneedham.com/blog/?p=1794</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/Dm-YNB8p0bk/</link>
	<description>&lt;p&gt;Something which I've noticed over the last few projects that I've worked on is that at the beginning when I don't know very much at all about the code base, domain and so on is that pairing with someone to TDD something seems to make it significantly easier for me to follow what's going on than other approaches I've seen.&lt;/p&gt;
&lt;p&gt;I thought that it was probably because I'm more used to that approach than any other but in Michael Feathers' description of TDD in '&lt;a href="http://www.amazon.com/gp/product/0131177052?ie=UTF8&amp;amp;tag=marneesblo-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0131177052"&gt;Working Effectively With Legacy Code&lt;/a&gt;' he points out the following:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
One of the most valuable things about TDD is that it &lt;strong&gt;lets us concentrate on one thing at a time&lt;/strong&gt;. We are either writing code or refactoring, we are never doing both at once.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;It also temporarily removes us from the feeling of drowning in all the new information which is typical at the start of projects. In a way it reminds me of the '&lt;a href="http://apprenticeship.oreilly.com/wiki/retreat_into_competence"&gt;Retreat Into Competence&lt;/a&gt;' pattern from '&lt;a href="http://www.amazon.com/gp/product/0596518382?ie=UTF8&amp;amp;tag=marneesblo-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0596518382"&gt;Apprenticeship Patterns&lt;/a&gt;' as it gives us a chance to regain composure and take in all the new information.&lt;/p&gt;
&lt;p&gt;We can probably make a much more useful contribution if we only need to understand one small piece of the system rather than having to understand everything which can often be the case with what Feathers coins the edit &amp;amp; pray approach to development.&lt;/p&gt;
&lt;p&gt;It's still necessary to spend some time trawling around the code base working out how everything fits together but I'm now more aware that it's also really useful to take some time to just focus on one much smaller class or piece of functionality.&lt;/p&gt;
&lt;p&gt;Perhaps also something to keep in mind the next time I'm pairing with someone who's new to a project that I've been working on for a while.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/MarkNeedham/~4/0x3QkU9w7Sw" height="1" width="1"&gt;&lt;/img&gt;</description>
	<pubDate>Fri, 06 Nov 2009 11:57:10 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/MarkNeedham/~3/0x3QkU9w7Sw/</feedburner:origLink></item>
<item>
	<title>Simon Brunning: Links for 2009-11-05 [del.icio.us]</title>
	<guid isPermaLink="false">http://del.icio.us/brunns#2009-11-05</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/YiMqIotaY7Y/brunns</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://studios.thoughtworks.com/mingle-agile-project-management/mingle-and-google-wave"&gt;Mingle + Google Wave for Project Collaboration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.twategy.com/"&gt;twategy inc&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
At least, I *hope* it's funny...&lt;/li&gt;
&lt;li&gt;&lt;a href="http://lifehacker.com/5396832/customize-mediawiki-into-your-ultimate-collaborative-web-site"&gt;Customize MediaWiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jaksview3.wordpress.com/2008/11/30/les-sapeurs-du-congo/"&gt;Les Sapeurs du Congo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gmailblog.blogspot.com/2009/11/choose-which-messages-get-downloaded.html"&gt;Customise GMail offline&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Superb&lt;/li&gt;
&lt;li&gt;&lt;a href="http://googleblog.blogspot.com/2009/11/transparency-choice-and-control-now.html"&gt;Google Dashboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Actor_model"&gt;Actor model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.linuxquestions.org/questions/linux-software-2/cant-mount-cd-unknown-filesystem-type-iso9660-766608/"&gt;Ubuntu 9.10: "unknown filesystem type 'iso9660'"&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Not just me then.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://apostrophe.me/"&gt;How To Use An Apostrophe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://news.bbc.co.uk/1/hi/magazine/8341002.stm"&gt;The rise of the non-veggie vegetarian&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Fri, 06 Nov 2009 08:00:00 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/SmallValuesOfCool/~3/lwarf4C0yd8/brunns</feedburner:origLink></item>
<item>
	<title>Tarek Abdelmaguid: Shouldn't We Local-Optimize at Bottlenecks?</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-2291554078837078852.post-7904347721055800088</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/XAFR7DSIl3U/shouldnt-we-local-optimize-at.html</link>
	<description>The short answer is no. Once we start thinking local, we are heading down the wrong path.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Consider what we should do at a bottleneck:&lt;br&gt;&lt;/br&gt;&lt;ul&gt;&lt;li&gt;Increase the resource's throughput, by increasing its efficiencies.&lt;/li&gt;&lt;li&gt;Manage the flow in the system to reduce idle time at the resource.&lt;/li&gt;&lt;li&gt;Add more capacity, by introducing other resources capable of the same function.&lt;/li&gt;&lt;li&gt;Outsource a portion of the work to resources outside the system.&lt;/li&gt;&lt;li&gt;Rethink the need for some work to go through the bottleneck.&lt;/li&gt;&lt;/ul&gt;You'd notice that only the first of these points is local in nature, and we should only consider it as an option. It may not be the best one.&lt;div class="blogger-post-footer"&gt;&lt;img src="https://blogger.googleusercontent.com/tracker/2291554078837078852-7904347721055800088?l=tabdelmaguid.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 06 Nov 2009 00:28:19 +0000</pubDate>
	<author>noreply@blogger.com (Tarek Abdelmaguid)</author>
<feedburner:origLink>http://tabdelmaguid.blogspot.com/2009/11/shouldnt-we-local-optimize-at.html</feedburner:origLink></item>
<item>
	<title>Felix Leipold: Objects as Functions in Java</title>
	<guid isPermaLink="false">http://wuetender-junger-mann.de/wordpress/?p=868</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/1Af8FRqXMY0/</link>
	<description>&lt;p&gt;
Earlier this year I wrote a &lt;a href="http://buildobjects.org"&gt;build tool&lt;/a&gt; in java. The core idea at the time was to express the build in terms of functions and function composition. This is not exactly a good fit with java. So last week I had some spare time and came up with this way of defining a function (application) in java:
&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre&gt; 
 &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #993333;"&gt;static&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; FancyFunction &lt;span style="color: #000000; font-weight: bold;"&gt;extends&lt;/span&gt; FunctionBase &lt;span style="color: #66cc66;"&gt;{&lt;/span&gt;
        @In
        &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;final&lt;/span&gt; Str a;
        @In
        &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;final&lt;/span&gt; Str b;
 
        @Out
        &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;final&lt;/span&gt; Str c = &lt;span style="color: #000000; font-weight: bold;"&gt;null&lt;/span&gt;;
        @Out
        &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;final&lt;/span&gt; Str d = &lt;span style="color: #000000; font-weight: bold;"&gt;null&lt;/span&gt;;
 
        &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; FancyFunction&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;Str a, Str b&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;{&lt;/span&gt;
            &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;a&lt;/span&gt; = a;
            &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006600;"&gt;b&lt;/span&gt; = b;
            super.&lt;span style="color: #006600;"&gt;reflect&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;;
        &lt;span style="color: #66cc66;"&gt;}&lt;/span&gt;
 
        &lt;span style="color: #000000; font-weight: bold;"&gt;protected&lt;/span&gt; &lt;span style="color: #993333;"&gt;void&lt;/span&gt; evaluate&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt; &lt;span style="color: #66cc66;"&gt;{&lt;/span&gt;
            setResult&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;c, &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; StrImpl&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;a.&lt;span style="color: #006600;"&gt;getValue&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt; + &lt;span style="color: #ff0000;"&gt;"-"&lt;/span&gt; + b.&lt;span style="color: #006600;"&gt;getValue&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;;
            setResult&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;d, &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; StrImpl&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;"XX"&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;;
        &lt;span style="color: #66cc66;"&gt;}&lt;/span&gt;
    &lt;span style="color: #66cc66;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
There is obviously a lot of magic going on and I do feel a bit bad abou setting final fields using reflection. 
&lt;/p&gt;
&lt;p&gt;
What it actually does is defining two functions. In a friendlier syntax somwhat like this:
&lt;/p&gt;

&lt;code&gt;&lt;pre&gt; 
fancy.&lt;span style="color: #006600;"&gt;c&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;a, b&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt; = a + &lt;span style="color: #3366CC;"&gt;"-"&lt;/span&gt; + b;
fancy.&lt;span style="color: #006600;"&gt;d&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;a, b&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt; = &lt;span style="color: #3366CC;"&gt;"XX"&lt;/span&gt;;&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;
But back to the java example, you can now compose applications like this:
&lt;/p&gt;&lt;p&gt;
&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre&gt; 
FancyFunction fun = &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; FancyFunction&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; StrImpl&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;"x"&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;, &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; StrImpl&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;"y"&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;;
FancyFunction fun2 = &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; FancyFunction&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;fun.&lt;span style="color: #006600;"&gt;c&lt;/span&gt;, &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; StrImpl&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;"z"&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;;
assertEquals&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;"x-y-z"&lt;/span&gt;, fun2.&lt;span style="color: #006600;"&gt;c&lt;/span&gt;.&lt;span style="color: #006600;"&gt;getValue&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;(&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;&lt;span style="color: #66cc66;"&gt;)&lt;/span&gt;;&lt;/pre&gt;
&lt;p&gt;
As this is all very reflective I could actually traverse the metadata and get &lt;a href="http://graphviz.org/"&gt;dot&lt;/a&gt; to render this:
&lt;/p&gt;
&lt;img src="http://wuetender-junger-mann.de/wordpress/wp-content/uploads/2009/11/test1.png" title="test" height="288" width="227" alt="test" class="alignnone size-full wp-image-870"&gt;&lt;/img&gt;

&lt;p&gt;
There is no code, as it is all very dirty. But to me it looks like a viable syntax for specifying tasks and wrapping imperative code into a functional style. The current implementation relies heavily on interfaces, because it generates a lot of proxies that allow for lazy evaluation.
&lt;/p&gt;</description>
	<pubDate>Thu, 05 Nov 2009 16:30:36 +0000</pubDate>
<feedburner:origLink>http://wuetender-junger-mann.de/wordpress/?p=868</feedburner:origLink></item>
<item>
	<title>Peter Gillard-Moss: Killing the Config</title>
	<guid isPermaLink="false">tag:blogger.com,1999:blog-6794675998088145034.post-2344824427162826443</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/DPC3TC4MBQM/killing-config.html</link>
	<description>Most applications require config of some description and it is considered good practice to wrap any calls which retrieve configured values in a config class and pass that around rather than &lt;a href="http://www.thekua.com/atwork/2008/08/treat-your-appconfig-like-a-global-variable/"&gt;splattering the codebase with direct calls to the frameworks inbuilt static methods&lt;/a&gt;.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;With all the applications configs neatly wrapped in one place the code starts to become more maintainable.  Yet are we just replacing one evil with another, if somewhat lesser, one?  The problem I often see is this Config class finds itself passed from class to class flouting it's promiscuity and leading writers of articles on config objects down paths dangerous and full of inappropriate metaphors more commonly favoured by the ruby crowd.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;There is no doubt that it is useful to collate all of the configurable elements together in one (or more) common classes.  What should be avoided is leaking this concept through the whole domain and kicking it from object to object like a dirty old data bag which everyone rumages through, unchecked, pulling out stuff on their own whim.  Config is an implementation detail which the majority of the application should have no concept of and (like any other such implementation details) it needs to be locked firmly away like a lump of kryptonite in a lead cased layer so it can no longer leak and permeate and weaken your SuperApp.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Let's think about this in a BDD fashion.  When your class want's a ghostbusting url who's it gonna call (they have a webpage now dinyuknow)?  string Config.GhostBusterUrl? Or perhaps the GhostBusterUrl class?  If your class needs a typed collaborator with certain logic and behaviour (even if it is just supplying a valid url) then that's what your class should get.  Not some smelly generic config object that dishes out dirty unparsed strings.  The tests should be enough to tell you I'm telling you the right thing: several lines of priming the mockConfig are replaced with the simple supply of a GhostbusterUrl.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;So how do we get the GhostBusterUrl from a line in config to those poor desperate classes who are being terrorized by spooks?  With a little Tell don't ask and a container.  Turn the config object inside out, make its role to inject into the application the dependencies it wants to supply.  If your config believes it has a GhostBusterUrl then get it to construct one and register it (along with anything else it thinks it might have of use) into the container when the application tells it to.  Not only does the config object gain some of its dignity back (some other classes were calling it nasty names, I know, it's the new millennium, but some people still hold the old fashioned ideas) and is safely kept right to the very edges of your application where no one can get at it.&lt;br&gt;&lt;/br&gt;&lt;br&gt;&lt;/br&gt;Another positive side effect is that now your config object is giving birth to loads of lovely typed objects that actually do real stuff rather than having wandering hands pluck at its primitives (I know but I did warn it was a dangerous path laden with tasteless innuendos, I was bound to trip).  Though of course, be careful not to pollute your codebase with a million classes that simply represent strings and do nothing else (it's a fine line and one you'll need to argue between me, myself and I).  It's also one of the easiest refactorings you can do to your code.  Give it a go (and if you object on the grounds of their being loads of small types then please find the closet crumbling procedural bridge and throw yourself into the polluted sequential river below).&lt;div class="blogger-post-footer"&gt;&lt;img src="https://blogger.googleusercontent.com/tracker/6794675998088145034-2344824427162826443?l=jupitermoonbeam.blogspot.com" height="1" width="1"&gt;&lt;/img&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 05 Nov 2009 10:13:58 +0000</pubDate>
	<author>noreply@blogger.com (Peter Gillard-Moss)</author>
<feedburner:origLink>http://jupitermoonbeam.blogspot.com/2009/11/killing-config.html</feedburner:origLink></item>
<item>
	<title>Simon Brunning: Links for 2009-11-04 [del.icio.us]</title>
	<guid isPermaLink="false">http://del.icio.us/brunns#2009-11-04</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/PWA2dxgDDTE/brunns</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.techcrunch.com/2009/11/04/thoughtworks-studios-rolls-out-new-version-of-mingle-integrates-with-google-wave/"&gt;ThoughtWorks Studios Rolls Out New Version Of Mingle, Integrates With Google Wave&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.guardian.co.uk/technology/gamesblog/2009/nov/03/borderlands-xbox-game-review"&gt;Game review | Borderlands&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
Oooooh&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mikebroberts.com/blogtastic/archives/239"&gt;The death of Agile&lt;/a&gt;&lt;br&gt;&lt;/br&gt;
At least he's nice about us.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://whygitisbetterthanx.com/"&gt;Why Git is Better Than X&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Thu, 05 Nov 2009 08:00:00 +0000</pubDate>
<feedburner:origLink>http://feedproxy.google.com/~r/SmallValuesOfCool/~3/E5yxcvy2ViA/brunns</feedburner:origLink></item>
<item>
	<title>James Crisp: Percent Number in Apache Rewrite Rules (mod_rewrite)</title>
	<guid isPermaLink="false">http://jamescrisp.org/2009/11/05/percent-number-in-apache-rewrite-rules-mod_rewrite/</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/h9PqmQUDAI0/</link>
	<description>&lt;p&gt;What do the %1 %2 in a Rewrite rule mean? The Apache guide does not help, nor does any other documentation I found. I came across the %1, %2 etc in some complex and arcane rules. Google ignores percent signs, which makes it hard to get an easy answer.&lt;/p&gt;
&lt;p&gt;We'll use the rules from my last post as an example.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RewriteCond %{HTTP_HOST} !^www\. [NC]&lt;br&gt;&lt;/br&gt;
RewriteCond %{HTTP_HOST} ^&lt;strong&gt;([a-z.]+)&lt;/strong&gt;$ [NC]&lt;br&gt;&lt;/br&gt;
RewriteRule ^/(.*)$ http://www.&lt;strong&gt;%1&lt;/strong&gt;/$1 [R=301,L]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The %1 refers to the capture group in a previous RewriteCond. This differentiates it from the $1 which refers to a capture group in the current RewriteRule.&lt;/p&gt;
&lt;p&gt;Hopefully I have littered this post with enough keywords that future googlers will find the answer to the %1 %2 in ReWrite rules more easily &lt;img src="http://jamescrisp.org/wordpress/wp-includes/images/smilies/icon_smile.gif" alt=":-)" class="wp-smiley"&gt;&lt;/img&gt;&lt;/p&gt;</description>
	<pubDate>Thu, 05 Nov 2009 01:16:49 +0000</pubDate>
<feedburner:origLink>http://jamescrisp.org/2009/11/05/percent-number-in-apache-rewrite-rules-mod_rewrite/</feedburner:origLink></item>
<item>
	<title>James Crisp: Adding WWW to domains, and Apache Rewrite Rules (mod_rewrite)</title>
	<guid isPermaLink="false">http://jamescrisp.org/2009/11/05/adding-the-www-subdomain-with-apache-rewrite-rules-mod_rewrite/</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/lJl7aSYFyEU/</link>
	<description>&lt;p&gt;Browse to &lt;a href="http://google.com" rel="external nofollow"&gt;http://google.com&lt;/a&gt;. Then look at the address bar. You're not really at &lt;a href="http://google.com" rel="external nofollow"&gt;http://google.com&lt;/a&gt;. You've been redirected to &lt;a href="http://www.google.com" rel="external nofollow"&gt;http://&lt;strong&gt;www.&lt;/strong&gt;google.com&lt;/a&gt;. Try the same on w3c, Facebook, Sydney Morning Herald etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why WWW?&lt;/strong&gt;&lt;br&gt;&lt;/br&gt;
Why do all these sites redirect you to a www form? Well, the main reason is because it is advantageous to have a canonical URL, and, if your have to choose one URL, you might as well go with what people seem to expect, which is to include a 'www'.&lt;/p&gt;
&lt;p&gt;What's so great about having one canonical URL?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cookies: if your users can access the site at www.domain.com and domain.com, you can end up with some horrible cookie and session problems depending on the browser and web framework (behaviour is different between Firefox and IE). Stay tuned for another post with more details on this.&lt;/li&gt;
&lt;li&gt;Certificates for HTTPS: certificates are usually for a single domain. If your site is available with and without 'www', your site will need a certificate for each or a multi-domain certificate (ie, more money and config).&lt;/li&gt;
&lt;li&gt;Caching: if you have two URLS, any HTTP caching will only be half as effective&lt;/li&gt;
&lt;li&gt;SEO: your page rank may be split between links to both possible URLs (though Google Webmaster tools seems to let you combine it)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;br&gt;&lt;/br&gt;
Right so, now you're probably just hoping there is an easy way to implement this forced 'www' business! Well the good news is that it's quite easy if you're using Apache with mod_rewrite. I googled around to try and find some good rules, but the ones I found were tied to a single hard coded domain (no good for me where I have multiple domains pointing to the same server for different countries). See below for what I came up with. It seems to work quite well. You can put it in your virtual host configuration file or even .htaccess file.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RewriteEngine on&lt;br&gt;&lt;/br&gt;
RewriteCond %{HTTP_HOST} !^www\. [NC]&lt;br&gt;&lt;/br&gt;
RewriteCond %{HTTP_HOST} ^([a-z.]+)$ [NC]&lt;br&gt;&lt;/br&gt;
RewriteRule ^/(.*)$ http://www.%1/$1 [R=301,L]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Line 1: Are you coming to the site without www. at the start of the host? [NC] means ignore case.&lt;/p&gt;
&lt;p&gt;Line 2: Does your domain comprise of letters and dots (this means that going to the IP address will not fire the rewrite rule). Grab the domain in a capture group.&lt;/p&gt;
&lt;p&gt;Line 3: Rewrite the URL with a www at the front, and keep the hostname from the previous condition (%1) and the path after the domain ($1). Use a status code 301, to tell the client that this is a permanent redirect.&lt;/p&gt;</description>
	<pubDate>Thu, 05 Nov 2009 00:54:45 +0000</pubDate>
<feedburner:origLink>http://jamescrisp.org/2009/11/05/adding-www-subdomain-with-apache-rewrite-rules-mod_rewrite/</feedburner:origLink></item>
<item>
	<title>Chad Wathington: Google Wave Integration</title>
	<guid isPermaLink="false">163493:1540691:5696924</guid>
	<link>http://feedproxy.google.com/~r/PlanetTw/~3/uuDgWjXitQc/google-wave-integration.html</link>
	<description>&lt;p&gt;Today, I presented at Enterprise 2.0 during the keynote with Greg D'alesandre from Google on Mingle Wave integration.  You can learn more about the integration here:&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://studios.thoughtworks.com/mingle-agile-project-management/mingle-and-google-wave"&gt;http://studios.thoughtworks.com/mingle-agile-project-management/mingle-and-google-wave&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Wed, 04 Nov 2009 18:45:22 +0000</pubDate>
<feedburner:origLink>http://chad.wathington.com/blog/2009/11/4/google-wave-integration.html</feedburner:origLink></item>

</channel>
</rss>
