<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/" xmlns:indexing="urn:atom-extension:indexing" indexing:index="no"><access:restriction xmlns:access="http://www.bloglines.com/about/specs/fac-1.0" relationship="deny"/>
  <title>Planet TW</title>
  <updated>2010-03-16T05:03:51Z</updated>
  <generator uri="http://intertwingly.net/code/venus/">Venus</generator>
  <author>
    <name>Test</name>
    <email>test@example.com</email>
  </author>
  <id>http://blogs.thoughtworks.com/atom.xml</id>
  <link href="http://blogs.thoughtworks.com/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://blogs.thoughtworks.com/" rel="alternate"/>

  <entry>
    <id>tag:blogger.com,1999:blog-21992362.post-2573791314803665153</id>
    <link href="http://blog.sriramnarayan.com/2010/03/agile-maintenance-support-evolution.html#comment-form" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/21992362/posts/default/2573791314803665153?v=2" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/21992362/posts/default/2573791314803665153?v=2" rel="self" type="application/atom+xml"/>
    <link href="http://blog.sriramnarayan.com/2010/03/agile-maintenance-support-evolution.html" rel="alternate" type="text/html"/>
    <title>Agile maintenance in a devops world</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">"What is an agile way of doing maintenance projects?", is a common question. An answer like the following is par for the course:<br/>
"It isn't very different from development projects. Write tests to reproduce bugs before you fix them. Treat enhancements as one or more stories. Keep the CI server running. Make sure that changes are occasionally merged from the maintenance branch into trunk. Pairing is probably not as important."<br/>
<br/>
In the context of this post, a 'maintenance' project is one where a client outsources ongoing bug-fixes and enhancements for a live application to an IT vendor (often offshore). Conventional wisdom has it that development is investment (capex) and maintenance is cost (opex). Hence, clients look for much lower billing rates when it comes to maintenance. This results in separate contracts/teams/vendors for development and maintenance. Some clients go a step further and outsource even IT operations to a different team/vendor under a separate contract. The rationale is to stick to core 'business competency' and outsource everything else (let them vendors compete with each other for our slice of IT).<br/>
<br/>
Depending on how critical the said application is for revenue generation, this strategy of 'divide-and-conquer-IT' can be frustrating at best and suicidal at worst. The best of the businesses that make most of their money off their websites outsource little to none of their IT. This is simply because you cannot go to market fast enough if you have to orchestrate between three teams/vendors for every new feature. Equally importantly, the feedback loop gets badly constricted at contractual boundaries. Designing formal, SLA driven protocols of communication between business, development, operations and maintenance is a recipe for bureaucracy and indifference.<br/>
<br/>
Not everyone can afford not to outsource. It is very difficult to put a good IT team in place. A lot of outsourcing has been a reaction to uncooperative in-house IT. But the solution has gone overboard in trying to compartmentalize development, operations and maintenance. You don't want to be overly reliant on a single vendor? Fair enough, consider outsourcing product A to vendor X, B to vendor Y and C to vendor Z. This is better than outsourcing the development of A, B, C to vendor X, operations to vendor Y and maintenance to vendor Z. The latter model requires well defined, stable interfaces between different constituencies. Not suitable where business is changing every week. It is a repeat of the <a href="http://dahliabock.wordpress.com/2009/08/06/why-i-think-layer-teams-are-a-bad-idea/" id="uaek" title="layered-team">layered-team</a> anti-pattern at a higher level.<br/>
<br/>
What if we want to deliver a grand SOA? Once the team of architects have specified every service, surely it should be possible to outsource a bunch of services to different vendors and the consuming applications to yet others. Splitting up integration work is extremely risky, in my opinion. Service contracts are rarely cast in stone. On the contrary, if you like the idea of evolutionary, guerrilla SOA, you no longer plan to have stable interfaces - the service evolves in tandem with the needs of its consumers. So, try to give all integration work and important applications to your primary vendor. Better yet, don't do big bang top down integration. Evolve bottom up.<br/>
<br/>
On the other hand, it may be that your business doesn't change that often or your application doesn't generate revenue. If so, it is useful to ask "Why build? Why not buy?" every once in a while. SaaS is growing fast. It is likely that someone is offering your bespoke application as a service. At the cost of some tweaks to your business process, you might end up with a better application at lower cost. The SaaS vendor in turn is likely running a full in-house IT.<br/>
<br/>
The world has changed yet again. <a href="http://www.kartar.net/2010/02/what-devops-means-to-me/" id="eicj" title="Devops">Devops</a> is <a href="http://www.devopsdays.org/" id="j89y" title="gaining">gaining</a> currency. These days, a common way of testing the uptake of new features is to divert, say 5% of your traffic to a new deployment and see how it goes. A separate maintenance team is a dinosaur in an age of frequent deployment (<a href="http://martinfowler.com/bliki/BlueGreenDeployment.html" id="p98n" title="blue-green">blue-green</a> or otherwise) and <a href="http://continuousdelivery.com/2010/02/continuous-delivery/#more-61" id="avvu" title="continuous delivery">continuous delivery</a>.<br/>
<br/>
Q. What is an agile way of doing maintenance projects?<br/>
A. Don't do maintenance as a separate project.<br/>
<br/>
There is one situation where a maintenance project might make sense. End-of-life support. Basically, you pay for a team to keep an old app running while a new replacement gets built. Other than that, it is all about breaking down silos.<br/>
<br/>
Of course, you will never hear Indian IT majors singing this tune. Their recruitment and business model is based on economies of scale. 'Changing businesses' are anathema to their ossified processes. However, in response to changing realities of the marketplace, some of them have begun to sing an agile tune. Some of them even claim to have proprietary, hybrid, high-performance methodologies that "synergize best of breed practices from CMMi, ISO, Six Sigma and Scrum". I'll explore a certain aspect of this 'synergy' in my next post.<div class="blogger-post-footer"><p style="text-align: right;"><a href="http://blog.sriramnarayan.com">blog home page</a></p><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/21992362-2573791314803665153?l=blog.sriramnarayan.com" width="1"/></div><img height="1" src="http://feeds.feedburner.com/~r/XploringAround/~4/9SwlaqwETDw" width="1"/></div>
    </content>
    <updated>2010-03-16T04:58:29Z</updated>
    <published>2010-03-15T07:43:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="agile-antipatterns"/>
    <author>
      <name>Sriram</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/01237485664035584743</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-21992362</id>
      <author>
        <name>Sriram</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/01237485664035584743</uri>
      </author>
      <link href="http://blog.sriramnarayan.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://blog.sriramnarayan.com/" rel="alternate" type="text/html"/>
      <link href="http://www.blogger.com/feeds/21992362/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;orderby=published&amp;v=2" rel="next" type="application/atom+xml"/>
      <link href="http://feeds.feedburner.com/XploringAround" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Sriram Narayan's blog on IT</subtitle>
      <title>XPloring around</title>
      <updated>2010-03-16T04:58:29Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.thekua.com/atwork/?p=918</id>
    <link href="http://www.thekua.com/atwork/2010/03/qcon-london-2010-day-2-2/" rel="alternate" type="text/html"/>
    <title>QCon London 2010 Day 2</title>
    <summary>Keynote: Ralph Johnson on Living and working with aging software
The final keynote of the conference kicked off the second day of QCon and presented to us by Ralph Johnson of the Gang of Four fame and whose students contributed to Fowler’s timeless Refactoring book. 
Ralph was asking about the number of people who work on [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p><strong>Keynote: Ralph Johnson on Living and working with aging software</strong><br/>
The final keynote of the conference kicked off the second day of QCon and presented to us by <a href="http://qconlondon.com/london-2010/speaker/Ralph+Johnson">Ralph Johnson</a> of the Gang of Four fame and whose students contributed to <a href="http://martinfowler.com/">Fowler’s</a> timeless <a href="http://www.amazon.com/exec/obidos/ASIN/0201485672">Refactoring</a> book. </p>
<p>Ralph was asking about the number of people who work on systems they created (versus systems that other created) and then argued about the meaning of maintenance programmer arguing for software evolutionists instead. Whilst I agree that no one likes to be labelled a maintenance programmer, changing the name doesn’t really matter. </p>
<p>I like the different perspectives that Ralph brought. He talked about <em>Software Capital</em> as about truly understanding how the software works. Code is one example of this, but actually there are many other things that go into understanding how the software works. He argues that the right sort of documentation (and other artefacts) that helps understand how the software works is another part of Software Capital. As a result, you also need the people around the software to help keep the story alive. </p>
<p>My observations of various organisations also backs up some of the things that he says such as, the larger a system gets, the more likely you need some form of documentation and social structure around the software. </p>
<p>I think a lot of people didn’t like Ralph’s keynote because he talked about refactoring as if it was a new idea and, unfortunately this audience is one that has been exposed to these ideas for a long time. </p>
<p><strong>Track: Beyond Tools and Technologies</strong><br/>
I spent the rest of my time on the <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=345">track</a> that I was speaking at later that day. The first talk of the day was Martin Fowler whose talk, “<em>What are we programming for?</em>” brought the tiny room to a stand still. The room was so full (although it was a small room) that they had to turn people away. </p>
<div style="text-align: center;"><a href="http://www.thekua.com/atwork/wp-content/uploads/2010/03/WhatAreWeProgrammingFor.jpg" rel="lightbox[pics918]" title="WhatAreWeProgrammingFor"><img alt="WhatAreWeProgrammingFor" class="attachment wp-att-919 " height="412" src="http://www.thekua.com/atwork/wp-content/uploads/2010/03/WhatAreWeProgrammingFor.jpg" width="550"/></a></div>
<p>Martin used the talk to highlight the importance of going beyond acting like hired guns and actually thinking about how to use the skills for something good. He asked people to consider the <em>essence</em> of the firms that they work for and whether or not they are benefiting humanity. </p>
<p><a href="http://www.thoughtworks.co.uk/who-we-are/leadership-profiles/rebecca-parsons.html">Rebecca Parsons</a>, ThoughtWorks’ CTO then talked about the importance of team diversity in her talk, “<em>How to avoid ‘We never even thought of that’!</em>” She talked about the role that diversity played in creating innovations in science and how too much of the “sameness” creates problems with creating too many assumptions. I like the idea of a balancing tradeoffs of not enough diversity leading to problems in teams and too much diversity to the point that the team don’t share the same vocabulary. </p>
<p>After the lunch break, I ran my session, “<em>Building the next generation of Technical Leaders</em>“. I was very happy with the turnout and had some great feedback from the participants. It’s an issues I think is sorely neglected in our industry and has a huge impact on the team effectiveness. </p>
<p>The next session was run by our Director of Social Engagement (Jeff Wishnie) and Merrick Schaefer of Unicef discussing the importance that technology has on developing countries and the significant impact it can have on the lives. They talked about the <a href="http://www.rapidftr.com/">Rapid FTR</a> project that is being developed to help capture information about children who’ve been separated from their parents with hope of quickly reconnecting them, and at worst, giving them legal status by registering them with an agency such as Unicef. </p>
<p>The final session of the day rounded out with Mick Blowfield with a presentation titled, “<em>IT in a Low Carbon Future</em>“.</p>
<p>Whilst there were many other potentially interesting sessions, I was really happy to hear about the issues that go beyond just <em>Tools and Technology</em>. </p></div>
    </content>
    <updated>2010-03-15T22:25:37Z</updated>
    <category term="Coaching"/>
    <category term="Development"/>
    <category term="Organisations"/>
    <category term="Philosophy"/>
    <author>
      <name>Patrick</name>
    </author>
    <source>
      <id>http://www.thekua.com/atwork</id>
      <link href="http://www.thekua.com/atwork/feed/" rel="self" type="application/atom+xml"/>
      <link href="http://www.thekua.com/atwork" rel="alternate" type="text/html"/>
      <subtitle>thekua's reflections on work related topics</subtitle>
      <title>thekua.com@work</title>
      <updated>2010-03-15T23:03:23Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-US">
    <id>163493:1540691:7024258</id>
    <link href="http://chad.wathington.com/blog/2010/3/15/cyndi-mitchell-talks-about-half-agile-in-sd-times.html" rel="alternate" type="text/html"/>
    <title>Cyndi Mitchell talks about half Agile in SD Times</title>
    <summary>But where mainstream agile adoption is  concerned, we are massively under-delivering on the potential of the  Agile movement and, by association, on our potential as software  professionals. We are failing to advance good agile engineering  practices at anywhere near the pace that we are advancing agile planning  practices.</summary>
    <updated>2010-03-15T22:14:43Z</updated>
    <author>
      <name>Chad Wathington</name>
    </author>
    <source>
      <id>http://chad.wathington.com/blog/</id>
      <link href="http://chad.wathington.com/blog/" rel="alternate" type="text/html"/>
      <link href="http://chad.wathington.com/blog/rss.xml" rel="self" type="application/rss+xml"/>
      <rights>Chad Wathington</rights>
      <subtitle>Chad Wathington's blog on Tech and Society</subtitle>
      <title>Tech Kindred</title>
      <updated>2010-03-16T05:02:24Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://iansrobinson.com/?p=215</id>
    <link href="http://iansrobinson.com/2010/03/15/the-counterintuitive-web/" rel="alternate" type="text/html"/>
    <link href="http://iansrobinson.com/2010/03/15/the-counterintuitive-web/#comments" rel="replies" type="text/html"/>
    <link href="http://iansrobinson.com/2010/03/15/the-counterintuitive-web/feed/atom/" rel="replies" type="application/atom+xml"/>
    <title xml:lang="en">The Counterintuitive Web</title>
    <summary xml:lang="en">The slides from last week’s talk at QCon, The Counterintuitive Web, are now available online. 

In the talk I described how we can implement rich and interesting business processes in (RESTful) Web applications, but only if we think in terms of protocol resources, not coarse-grained domain resources. By embracing the Web as first and foremost [...]</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p>The slides from last week’s talk at QCon, <a href="http://qconlondon.com/london-2010/presentation/The+Counterintuitive+Web" target="_blank" title="The Counterintuitive Web"><em>The Counterintuitive Web</em></a>, are now <a href="http://qconlondon.com/london-2010/file?path=/qcon-london-2010/slides/IanRobinson_TheCounterintuitiveWeb.pdf" target="_blank" title="Slides (11 MB)">available online</a>.</p> 

<p>In the talk I described how we can implement rich and interesting business processes in (RESTful) Web applications, but only if we think in terms of protocol resources, not coarse-grained domain resources. By embracing the Web as first and foremost a web of data, an open set of resource representations manipulated in the same-old-same-old ways using a closed set of verbs, our designs capture the behaviours most CRUD-based, data-centric applications so sorely lack.</p>

<p>Many thanks to <a href="http://dannorth.net/" target="_blank" title="Dan North's blog">Dan North</a> for inviting me to speak on his <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=329" target="_blank" title="Irresponsible Architectures and Unusual Architects"><em>Irresponsible Architectures and Unusual Architects</em></a> track.</p></div>
    </content>
    <updated>2010-03-15T12:47:53Z</updated>
    <published>2010-03-15T12:47:53Z</published>
    <category scheme="http://iansrobinson.com" term="Events"/>
    <category scheme="http://iansrobinson.com" term="REST"/>
    <author>
      <name>iansrobinson</name>
      <uri>http://www.iansrobinson.com</uri>
    </author>
    <source>
      <id>http://iansrobinson.com/feed/atom/</id>
      <link href="http://iansrobinson.com" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/iansrobinson" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle xml:lang="en">Ian Robinson's Blog</subtitle>
      <title xml:lang="en">iansrobinson.com</title>
      <updated>2010-03-15T12:47:53Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:typepad.com,2003:post-6a01156f76f3eb970c0120a939fd51970b</id>
    <link href="http://www.apcjones.com/blog/2010/03/size-of-your-head.html" rel="alternate" type="text/html"/>
    <link href="http://www.apcjones.com/blog/2010/03/size-of-your-head.html" rel="replies" type="text/html"/>
    <title>Size of your head</title>
    <summary>Not-very-small tablet PC, via Wired.</summary>
    <content type="xhtml" xml:lang="en-US"><div xmlns="http://www.w3.org/1999/xhtml"><a href="http://www.wired.com/reviews/product/pr_archos_9">
<img alt="Archos" src="http://www.wired.com/images/productreviews/2010/03/archos_f4.jpg"/>
</a>
<p>Not-very-small tablet PC, via <a href="http://www.wired.com/reviews/product/pr_archos_9">Wired</a>.</p></div>
    </content>
    <updated>2010-03-15T09:35:27Z</updated>
    <published>2010-03-15T09:35:27Z</published>
    <author>
      <name>Alistair Jones</name>
    </author>
    <source>
      <id>tag:typepad.com,2003:weblog-1866507</id>
      <link href="http://www.apcjones.com/blog/atom.xml" rel="self" type="application/atom+xml"/>
      <link href="http://hubbub.api.typepad.com/" rel="hub" type="text/html"/>
      <link href="http://www.apcjones.com/blog/" rel="alternate" type="text/html"/>
      <title>Alistair Jones Blog</title>
      <updated>2010-03-15T09:35:27Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://watchitlater.com/blog/?p=198</id>
    <link href="http://watchitlater.com/blog/2010/03/update-to-s3dropbox/" rel="alternate" type="text/html"/>
    <title>Update to S3DropBox</title>
    <summary>I’ve released a new version of my S3DropBox. You can now right-click on any file to download it, delete it or create a public link to it. Comments, feedback and bugs are always welcome.</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I’ve released a new version of my <a href="http://code.google.com/p/s3dropbox/">S3DropBox</a>. You can now right-click on any file to download it, delete it or create a public link to it. Comments, feedback and bugs are always welcome.</p></div>
    </content>
    <updated>2010-03-15T01:24:59Z</updated>
    <category term="My Code"/>
    <category term="Amazon"/>
    <category term="Java"/>
    <category term="S3"/>
    <author>
      <name>Tom</name>
    </author>
    <source>
      <id>http://watchitlater.com/blog</id>
      <link href="http://watchitlater.com/blog/feed/" rel="self" type="application/atom+xml"/>
      <link href="http://watchitlater.com/blog" rel="alternate" type="text/html"/>
      <subtitle>A reluctant foray into the world of blogging.</subtitle>
      <title>No One Is Perfect</title>
      <updated>2010-03-15T02:03:49Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.markhneedham.com/blog/?p=2259</id>
    <link href="http://feedproxy.google.com/~r/MarkNeedham/~3/PhBtKF6D7CE/" rel="alternate" type="text/html"/>
    <title>node.js: First thoughts</title>
    <summary>I recently came across node.js via a blog post by Paul Gross and I've been playing around with it a bit over the weekend trying to hook up some code to call through to the Twitter API and then return the tweets on my friend timeline.
node.js gives us event driven I/O using JavaScript running server [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I recently came across <a href="http://nodejs.org/">node.js</a> via <a href="http://www.pgrs.net/2010/2/28/node-js-redis-and-resque">a blog post by Paul Gross</a> and I've been playing around with it a bit over the weekend trying to hook up some code to call through to the Twitter API and then return the tweets on my friend timeline.</p>
<p>node.js gives us event driven I/O using JavaScript running server side on top of <a href="http://code.google.com/p/v8/">Google's V8 JavaScript engine</a>.</p>
<p>Simon Willison has <a href="http://www.slideshare.net/simon/evented-io-based-web-servers-explained-using-bunnies - Simon Willison's talk">part of a presentation on slideshare</a> where he describes the difference between the typical thread per request approach and the event based approach to dealing with web requests using the metaphor of bunnies. He also has <a href="http://simonwillison.net/2009/Nov/23/node/">a blog post where he describes this is more detail</a>.</p>
<p>Another resource I found useful is <a href="http://jsconfeu.blip.tv/file/2899135/">a video from jsconf.eu</a> where the creator of node.js, Ryan Dahl, explains the philosophy behind event driven I/O and gives several examples using node.js.</p>
<p>These are some of my thoughts so far:</p>
<ul>
<li>I'm not used to have <a href="http://en.wikipedia.org/wiki/Event-driven_programming">so many callbacks spread all around the code</a> and I'm still getting used to the idea that they aren't executed until the event actually happens!
<p>I often find myself looking at a piece of code and not understanding how it can possibly work because I'm assuming that the function passed in is executed immediately when in fact it isn't.
</p></li>
<li>If you make a web request the response comes back in chunks so the callback we setup to capture the response will be called multiple times with different parts of the response message.
<p>For example I have this code to call Twitter and return all my friends' status updates:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> sys <span style="color: #339933;">=</span> require<span style="color: #009900;">(</span><span style="color: #3366CC;">"sys"</span><span style="color: #009900;">)</span><span style="color: #339933;">,</span>
    http <span style="color: #339933;">=</span> require<span style="color: #009900;">(</span><span style="color: #3366CC;">'http'</span><span style="color: #009900;">)</span>
 
exports.<span style="color: #006600;">getTweets</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span>callBack<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    <span style="color: #003366; font-weight: bold;">var</span> twitter <span style="color: #339933;">=</span> http.<span style="color: #006600;">createClient</span><span style="color: #009900;">(</span><span style="color: #CC0000;">80</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">"www.twitter.com"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> request <span style="color: #339933;">=</span> twitter.<span style="color: #006600;">request</span><span style="color: #009900;">(</span><span style="color: #3366CC;">"GET"</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">"/statuses/friends_timeline.json"</span><span style="color: #339933;">,</span>
                                  <span style="color: #009900;">{</span><span style="color: #3366CC;">"host"</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">"www.twitter.com"</span><span style="color: #339933;">,</span>
                                   <span style="color: #3366CC;">"Authorization"</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">"Basic "</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">"xxx"</span><span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
 
    request.<span style="color: #006600;">addListener</span><span style="color: #009900;">(</span><span style="color: #3366CC;">'response'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">(</span>response<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
        <span style="color: #003366; font-weight: bold;">var</span> tweets <span style="color: #339933;">=</span> <span style="color: #3366CC;">""</span><span style="color: #339933;">;</span>
 
        response.<span style="color: #006600;">addListener</span><span style="color: #009900;">(</span><span style="color: #3366CC;">"data"</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">(</span>chunk<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
            tweets <span style="color: #339933;">+=</span> chunk<span style="color: #339933;">;</span>
        <span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
 
        response.<span style="color: #006600;">addListener</span><span style="color: #009900;">(</span><span style="color: #3366CC;">"end"</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
            callBack.<span style="color: #006600;">call</span><span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> tweets<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
 
    request.<span style="color: #000066;">close</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span><span style="color: #339933;">;</span></pre></div></div>

<p>I originally thought that the listener for 'data' would only be called once but it gets called 8 times sometimes so that I've created the 'tweets' variable which allows us to wait until we have the full response before firing the callback when the 'end' event is fired.</p>
<p>I'm not sure whether I'm missing the point a bit by doing this and I think I possibly need to get more used to designing functions which can deal with streams rather than expecting to have all of the data.</p></li>
<li>It seems like node.js would be perfect for a version of <a href="http://code.google.com/p/http-impersonator/">my colleagues Julio Maia and Fabio Lessa's  http-impersonator</a> which is a Java application used to record and replay requests/responses made across http-based protocols.
<p>I haven't quite worked out the best way to test the above code – ideally I want to stub out the HTTP request so that the test doesn't have to go across the wire. Micheil Smith pointed me towards <a href="http://fakeweb.rubyforge.org/">fakeweb</a> which allows the faking of HTTP requests/responses in Ruby so I'll probably have a go at creating something similar. </p></li>
</ul>
<p>So far node.js seems really cool and writing code using it is really fun. I'm still not sure exactly where it will fit in some of the architectures that I've worked on but the model it encourages feels really natural to work with.</p>
<img height="1" src="http://feeds.feedburner.com/~r/MarkNeedham/~4/PhBtKF6D7CE" width="1"/></div>
    </content>
    <updated>2010-03-15T00:09:47Z</updated>
    <category term="Javascript"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.markhneedham.com/blog/2010/03/15/node-js-first-thoughts/</feedburner:origlink>
    <author>
      <name>Mark Needham</name>
    </author>
    <source>
      <id>http://www.markhneedham.com/blog</id>
      <link href="http://www.markhneedham.com/blog" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/MarkNeedham" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Thoughts on Software Development</subtitle>
      <title>Mark Needham</title>
      <updated>2010-03-15T01:04:09Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.thekua.com/atwork/?p=912</id>
    <link href="http://www.thekua.com/atwork/2010/03/qcon-london-2010-day-1/" rel="alternate" type="text/html"/>
    <title>QCon London 2010 Day 1</title>
    <summary>I’ve never been to a QCon before and being run by the same organisers of JAOO and the folks behind the ever popular InfoQ, I was looking forward to being both an attendant and presenter. Lasting three conference days and two tutorial days, this conference focuses mainly on being talked at – quite a different [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I’ve never been to a <a href="http://qconlondon.com/">QCon</a> before and being run by the same organisers of <a href="http://jaoo.dk/">JAOO</a> and the folks behind the ever popular <a href="http://www.infoq.com/">InfoQ</a>, I was looking forward to being both an attendant and presenter. Lasting three conference days and two tutorial days, this conference focuses mainly on being talked at – quite a different experience to the Agile 20xx and the XP 20xx conferences I normally run workshops/talks at. Being focused on the cutting edge and practical technologies side, I can really understand this because it’s hard to target people with the right level of experience. </p>
<p>Talking to most of the attendees, it also attracts a noticeably different side with the majority of people already in architect or senior developer roles with a relatively smaller proportion of people in other ancillary roles such as PMs, testers or BAs. </p>
<p><strong>Feedback that works</strong><br/>
I like the feedback note for the conference, asking people tweet, email or talk to people at the conference. I think some of the feedback mechanisms even worked as we saw a lack of caffeine/water during the breaks on the first day change for the other remaining days. </p>
<p><strong>The Keynote</strong><br/>
The first day’s keynote started with the evangelical <a href="http://www.objectmentor.com/omTeam/martin_r.html">Uncle Bob Martin</a>. He’s a great speaker and channels a lot of opinion towards the crowd wandering back and forth on stage. I saw a version of this at the <a href="http://agile2009.org/">Agile 2009</a> conference. I’m glad he adjusted it somewhat more appropriately for this conference. He talked about some good principles that should be followed after a few bumpy technical glitches. He is all about the drama (which I guess is part and parcel of a keynote) such as showing us a video that scrolled through a single java class for something like two to three minutes backed up by a song from the movie from 2001 (thanks Ola!) <span style="text-decoration: line-through;">that almost sounded like the flight of the bumblebee</span>. The point of this showmanship was to demonstrate how we can sense bad code visually without even looking at the specifics. He went through a number of his mantras such as “The Boy Scout” rule, leaving things better than how you found them, or that functions should be no more than four or five lines long. </p>
<p>Whilst I don’t think I learned anything new, Uncle Bob Martin was entertaining and had good things to say, despite how preacher-like he comes across. </p>
<p><strong>Track: Architecture’s You’ve Always Wondered About – Session: BWin – P5 a future proof poker platform</strong><br/>
The rest of the day was split into six different tracks. I went to the first of these and was truly disappointed. The two presenters came from <a href="https://www.bwin.com/" rel="nofollow">BWin</a>, apparently one of the largest poker and gaming sites in Europe. They spent half an hour talking about their problems of performance (many of the -iliites) and where the history of their application came from. They even had to include a three minute video from their marketing folks. They finally flashed up a screenshot of their architecture diagram which I think everyone had come to hear about it. Unfortunately they moved onto the next screen very quickly and said that they couldn’t actually talk about their architecture. How disappointing! Indeed this might have been an “Architecture You’ve Always Wondered About”, and after this session was one to still, indeed, wonder about it. </p>
<p>They proceeded to pick a single example about two processes that concurrently wrote and read from the same database table and their architectural change simply transitioning it to a disk persistent queue and the reporting service reading from that queue and writing to its own database. Neither very profound, or a very interesting tidbit that failed to give the audience any more insight into any interesting part of how they architected their system. </p>
<p>I found it interesting they spent a long time (something like 250 man years) rewriting this version of their architecture so I asked the question about how they went about moving from their old to their new platform at which they pretty much described a big bang approach – neither iterative or incremental. Pretty disappointing. </p>
<p><em>My lesson learned from this</em>: Regardless of how pretty your slides are, make sure your abstract matches what you’re going to actually talk about. </p>
<p><strong>Track: Dev and Ops: A Single Team – Session: Devs and Ops Cooperation when the Worst Happens</strong><br/>
My next session was much more fulfilling with <a href="http://www.michaelnygard.com/">Michale Nygard</a> (author of <a href="http://www.pragprog.com/titles/mnee/release-it">Release It</a>) describing some of the stories that were the basis for the book but wouldn’t have been publishable. Michael is really down to earth and happy to chat about many of the details behind the book. It’s really obvious that he is also a very pragmatic person, understanding that models are just that and recommending people look into the details because there is often something much more complex underneath. </p>
<p>Many of the things that Michael talked about also resonated very strongly with ideas that I’ve seen on applications. Many of them included focusing on ensuring documentation artefacts should be tested by those who will consume them. As he put it, “UML is virtually useless to the deployment and operations team”. Other gems included, “From a high enough view, everything starts to look the same”</p>
<p>His stories also reinforced the importance of having a ubiquitous language will all members of the company in the shared domain. One of his most successful rescue missions dealing with a production problem only worked because the architect (on the dev side) and Michael (on the ops side) understood enough to really communicate the real problems.  Michael also kept (understandably) hammering home the point of lack of information on both sides really hurts the problem solving process. </p>
<p>A lot of Michael’s stories also described their successes working around the existing (organisational) systems in order to deal with the problems at hand. To me, this was just another great example of organisations that structure themselves for efficiency over effectiveness. </p>
<p>I like the way that Michael finished off his talk as well, focusing on the fact that you’re not just trying to build software, that you need to care about the organisation (and I would also argue, the systems and procedures in that organisation) that support the software. Design them for effectiveness, not efficiency.</p>
<p><strong>Architectures you’ve always wondered about: Facebook</strong><br/>
The next session I attended was by Aditya Agarwal (one of the engineering directors of Facebook). He shared some great insights and lessons learned into what things Facebook did that got them to where they were. Admittedly they had some strange choices like writing something that converted PHP into compiled C++ and using MySQL is a very “reliable bitstore”. </p>
<p>They have a lot of great things to say, like being very proud of the low number of engineers ratio to actual users. Like Alistair, I’m puzzled why they’re secretive of the exact number of their employees. </p>
<p>Aditya has some good things to say and although he means well, I don’t support everything that he says. it’s obvious a lot of what he says is based on a start up culture. Things like, “don’t worry about it until it becomes a problem” encourages the recklessness we see in many software companies. Same thing about the choice of programming language such as “every programming language will have problems at our scale”. </p>
<p>On the plus side, I was pleased to hear them encouraging the innovative engineering culture that I don’t see in many organisations. </p>
<p><strong>Track: Non relational DBs and Web Oriented Data – Session: Social networks and the richness of data: getting it done with</strong><br/>
After going through my notes the most interesting tidbit was about using a partitioning mechanism to deal with data updates based on the number of connections. There was plenty of buzzwords (both internal and external) that I think I had a hard time fitting it all together. Some things I’m going to look at include:</p>
<ul>
<li>Bit versus <a href="http://en.wikipedia.org/wiki/Bloom_filter">bloom</a> filters – Not familiar with this term or how to use it.</li>
<li>Tools – <a href="http://www.jboss.org/resteasy">RESTeasy</a> (I now see it’s a JBoss project). <a href="http://code.google.com/p/redis/">Redis</a> and <a href="http://project-voldemort.com/">Voldemort</a> – something they used heavily all over the place.</li>
</ul>
<p>That’s about all I got out of this session though I’m not sure if it was about the lack of familiarity with the tools, or the excessive use of acronyms and unfamiliar terms or just plain tiredness. </p>
<p><strong>Track: Functional Programming – Session: Demystifying Monads</strong><br/>
<a href="http://grahamis.com/blog">Josh Graham</a> did a great job stepping into fill in for his ill wife talking through some of the different ideas behind monads. I haven’t done functional programming since university and I’ll be the first to admit Monad’s are still a mystery to me but I came away with some key learnings. </p>
<p>Firstly, to understand monads properly, you really just have to see several examples in action. There’s a high barrier to entry  because it means:</p>
<ol>
<li>Learning a new language</li>
<li>Learning a new development environment</li>
<li>Playing with plenty of examples</li>
</ol>
<p>When I find some time, I’ll do those. In the meantime, I understand a bit more about the properties of a monad, and that they can be a powerful abstraction for functional languages. </p>
<p><strong>Final keynote – <a href="http://en.wikipedia.org/wiki/Daniel_Henry_Holmes_Ingalls,_Jr.">Dan Ingalls</a>: Forty Years of Fun with Computers</strong><br/>
For being so late in the day, this was a very entertaining keynote. Just like any modern day small talk person, this entire demonstration took place in the <a href="http://www.squeak.org/">Squeak</a> development environment. Dan demonstrated some interesting and interactive elements. </p>
<p>I had a few key takeaways including:</p>
<ul>
<li>We’re really bad at learning the lessons from the past. Partially because we don’t have enough storytellers and that our generation doesn’t listen very well. </li>
<li>I’m going to read <a href="http://www.smalltalk.org/smalltalk/TheEarlyHistoryOfSmalltalk_Abstract.html">this article</a> at some point. </li>
</ul></div>
    </content>
    <updated>2010-03-14T18:20:40Z</updated>
    <category term="Conferences"/>
    <category term="Development"/>
    <category term="Organisational"/>
    <author>
      <name>Patrick</name>
    </author>
    <source>
      <id>http://www.thekua.com/atwork</id>
      <link href="http://www.thekua.com/atwork/feed/" rel="self" type="application/atom+xml"/>
      <link href="http://www.thekua.com/atwork" rel="alternate" type="text/html"/>
      <subtitle>thekua's reflections on work related topics</subtitle>
      <title>thekua.com@work</title>
      <updated>2010-03-15T23:03:23Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-24663619.post-2092729474224358695</id>
    <link href="http://agileanalysis.blogspot.com/feeds/2092729474224358695/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="https://www.blogger.com/comment.g?blogID=24663619&amp;postID=2092729474224358695" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/24663619/posts/default/2092729474224358695?v=2" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/24663619/posts/default/2092729474224358695?v=2" rel="self" type="application/atom+xml"/>
    <link href="http://feedproxy.google.com/~r/agilebusinessanalysis/~3/toQ8G2ZMf5I/testing-considered-wasteful.html" rel="alternate" type="text/html"/>
    <title>Testing considered wasteful??</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">@silvercatalyst posted on twitter a few days back that one of the trainees in his session counted testing as waste. I retweeted with a #funny but @silvercatalyst said he actually agreed with it. So...<img height="1" src="http://feeds.feedburner.com/~r/agilebusinessanalysis/~4/toQ8G2ZMf5I" width="1"/></div>
    </content>
    <updated>2010-03-14T11:31:24Z</updated>
    <published>2010-02-18T20:27:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="agile"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="feature injection"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="twitter"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="cross-functional pairing"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="business analysis"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://agileanalysis.blogspot.com/2010/02/testing-considered-wasteful.html</feedburner:origlink>
    <author>
      <name>Akshay Dhavle</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/03105245771080772055</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-24663619</id>
      <author>
        <name>Akshay Dhavle</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/03105245771080772055</uri>
      </author>
      <link href="http://agileanalysis.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://agileanalysis.blogspot.com/" rel="alternate" type="text/html"/>
      <link href="http://www.blogger.com/feeds/24663619/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" rel="next" type="application/atom+xml"/>
      <link href="http://feeds.feedburner.com/agilebusinessanalysis" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Random attempts to write about my philosophy and experiences with business analysis using agile methodologies at a wonderful place called ThoughtWorks...</subtitle>
      <title>Business Analysis</title>
      <updated>2010-03-15T03:18:51Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-8396317.post-9149351698019818566</id>
    <link href="http://www.learninggeneralist.com/feeds/9149351698019818566/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="https://www.blogger.com/comment.g?blogID=8396317&amp;postID=9149351698019818566" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/8396317/posts/default/9149351698019818566?v=2" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/8396317/posts/default/9149351698019818566?v=2" rel="self" type="application/atom+xml"/>
    <link href="http://feedproxy.google.com/~r/blogspot/sawZ/~3/kVDB-QN9Azo/lets-tackle-gender-diversity-as.html" rel="alternate" type="text/html"/>
    <title>Let's tackle Gender Diversity as a Systemic Issue</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><img alt="" src="http://farm1.static.flickr.com/140/323461344_6a075fbe14.jpg" style="margin: 0pt auto 10px; display: block; text-align: center;" title=""/>Yet again, I'm writing a blog-post at the airport! Over the last couple of days I've been part of a very keen set of discussions in the HR space. One of the topics we touched upon was Diversity, particularly in the IT industry. We discussed means to increase the number of women in the company and to keep them supported, but while in those discussions, I felt that the lack of women in the industry is perhaps a systemic problem. The real reasons for a lack of enough women in IT feel like:<br/><ol><li>not many women study or have an interest in computer science;</li><li>women are subject to a number of socio-cultural pressures that men aren't a part of;</li><li>in a male dominated industry, there are very few women role-models to look upto - resulting again in #1 above.</li></ol>Fixing these root causes seems like a huge program of change beyond just providing a few measures at work. Here are a few thoughts I have about actually increasing gender diversity in IT.<br/><br/><h3>Tackle the problem at the Grassroots -- target students</h3><br/>All across the world, computer science doesn't seem to be a hugely popular discipline with young girls. The key could be to introduce young girls to the magic of programming at an early age. One of the projects that really excites me is <a href="http://www.alice.org/">Alice</a>. Alice is an innovative 3D programming environment that makes it easy to create an animation for telling a story, playing an interactive game, or a video to share on the web. Alice is a teaching tool for introductory computing. It uses 3D graphics and a drag-and-drop interface to facilitate a more engaging, less frustrating first programming experience. Alice allows children to learn through a <a href="http://www.google.co.uk/url?sa=t&amp;source=web&amp;ct=res&amp;cd=7&amp;ved=0CCIQFjAG&amp;url=http%3A%2F%2Fwww.associatedcontent.com%2Farticle%2F604505%2Flife_lessons_and_the_randy_pausch_head.html&amp;ei=4IObS7yEHdW7jAeR19GTDA&amp;usg=AFQjCNEDZ2Huv4_m22RiQq7tU_VYbjg1iQ&amp;sig2=IPxc2wx5n58OfrZZU1Y2gA">head-fake</a> -- they believe they're playing a game, but on the sidelines they're actually writing a program in a modern object oriented language such as Java. Prentice Hall has gone to the extent of creating <a href="http://www.aliceprogramming.net/">instructional materials</a> to actually teach students how to program, using Alice as the teaching tool! Could companies support the educational system by sending their experts to schools and universities using Alice as a a teaching platform. That way we can introduce computer science as a discipline that's just as interesting and creative as management or humanities.<br/><br/><h3>Join Forces in the Industry</h3>While a single company may not have many women superstars, there's absolutely no dearth of thought leadership from women in IT. Often we make the mistake of trying to solve our gender diversity problems in isolation. It may not be a bad idea for like minded companies to join forces and seek out great female potential by using their role model women as hiring ambassadors. A women only career fair with superstar women representatives from various companies could actually help other ladies be attracted to computer science as a career. In general, these alliances need to be strategic -- short term alliances are likely to be frustrating, but longer term alliances may actually allow organisations to build on each other's successes.<br/><br/><h3>Recognise Socio-cultural Influences -- Experiment with Next-gen Tools</h3><img alt="" src="http://4.bp.blogspot.com/_6wLxMwoRK6c/SnhsXd30IaI/AAAAAAAABZ8/_rT1qG1EO-E/s320/ProtoSphere.bmp" style="margin: 0pt auto 10px; display: block; text-align: center;" title=""/>The webvolution, and immersive internet presents us with some very interesting possibilities. There's no doubt that the technology is still immature, but companies need to still start experimenting with virtual worlds as a way to create real-time, synchronous workspaces. Women, particularly in India are under the influence of great socio-cultural pressures. The ability to work from home and still enjoy a high degree of collaboration could be invaluable in increasing diversity. <a href="http://karlkapp.blogspot.com/">Karl Kapp</a> is a great proponent of such technology and I think that when we can actually make 3D technology an inseparable part of work a few years from now, companies will enjoy significant advantages in addition to being able to increase their diversity. Here are some obvious advantages that come to mind:<br/><ul><li>lower investment on facilities -- possibly lower opex;</li><li>lower cost of commute;</li><li>lower pollution levels as a result of lower cost of transport;</li><li>lower carbon footprint as a result of reduced travel;</li><li>better salaries as a consequence of money saved on lease, office space, etc;</li><li>faster growth of business as a consequence of virtual workspaces and the ability to invest elsewhere.</li></ul><hr/>What other ideas do you have to increase gender diversity in the IT sector? ThoughtWorks is keen to right the wrongs of this industry in it's own small way and I can try to channel some of your suggestions in the right direction. Let me know what you think by adding your thoughts in the comments section.<br/><br/><font size="1"><span style="font-weight: bold;">Photo credit:</span> <a href="http://www.flickr.com/photos/chrisjfry">chrisjfry</a> under the Creative Commons and <a href="http://karlkapp.blogspot.com/">Dr. Karl Kapp</a> for the Protoshpere screenshot.</font><div class="blogger-post-footer">© Sumeet Moghe, 2009<img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/8396317-9149351698019818566?l=www.learninggeneralist.com" width="1"/></div></div>
    </content>
    <updated>2010-03-14T08:01:16Z</updated>
    <published>2010-03-13T12:47:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="tools"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="technology"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="people"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="diversity"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="human resources"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.learninggeneralist.com/2010/03/lets-tackle-gender-diversity-as.html</feedburner:origlink>
    <author>
      <name>Sumeet Moghe</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/15085919050832112976</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-8396317</id>
      <logo>http://creativecommons.org/images/public/somerights20.gif</logo>
      <author>
        <name>Sumeet Moghe</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/15085919050832112976</uri>
      </author>
      <link href="http://www.learninggeneralist.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.learninggeneralist.com/" rel="alternate" type="text/html"/>
      <link href="http://www.blogger.com/feeds/8396317/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" rel="next" type="application/atom+xml"/>
      <link href="http://feeds.feedburner.com/blogspot/sawZ" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://creativecommons.org/licenses/by-nc-sa/3.0/" rel="license" type="text/html"/>
      <subtitle>If you always do what you've always done, you'll always get what you always got and there is always more</subtitle>
      <title>Free as in Freedom</title>
      <updated>2010-03-14T08:01:15Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://del.icio.us/brunns#2010-03-13</id>
    <link href="http://feedproxy.google.com/~r/SmallValuesOfCool/~3/ngLeBAKlvR4/brunns" rel="alternate" type="text/html"/>
    <title>Links for 2010-03-13 [del.icio.us]</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><ul>
<li><a href="http://www.quotegarden.com/alcohol.html">Alcohol Quotes</a></li>
<li><a href="http://www.cs.brown.edu/people/acb/codebubbles_site.htm">Code Bubbles Project: Rethinking the User Interface Paradigm of Integrated Development Environments</a></li>
<li><a href="http://hackaday.com/2010/03/10/jeri-makes-integrated-circuits/">Jeri makes integrated circuits</a></li>
</ul></div>
    </summary>
    <updated>2010-03-14T08:00:00Z</updated><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://del.icio.us/brunns#2010-03-13</feedburner:origlink>
    <source>
      <id>http://www.brunningonline.net/simon/blog/</id>
      <author>
        <name>Simon Brunning</name>
        <email>simon.brunning+smallvaluescomment@gmail.com</email>
      </author>
      <link href="http://www.brunningonline.net/simon/blog/" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/SmallValuesOfCool" rel="self" type="application/rss+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <rights>Copyright 2010</rights>
      <subtitle>Simon Brunning - stuff that I find interesting</subtitle>
      <title>Small Values of Cool</title>
      <updated>2008-10-08T13:18:28Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.markhneedham.com/blog/?p=2255</id>
    <link href="http://feedproxy.google.com/~r/MarkNeedham/~3/OuYLhbigDSk/" rel="alternate" type="text/html"/>
    <title>A reminder of the usefulness of Git</title>
    <summary>Despite the fact that none of the projects that I've worked on have used Git or Mercurial as the team's main repository I keep forgetting how useful those tools can be even if they're just being used locally.
I ran into a problem when trying to work out why a Rhino Mocks expectation wasn't working as [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Despite the fact that none of the projects that I've worked on have used <a href="http://git-scm.com/">Git</a> or <a href="http://mercurial.selenic.com/">Mercurial</a> as the team's main repository I keep forgetting how useful those tools can be even if they're just being used locally.</p>
<p>I ran into a problem when trying to work out why a Rhino Mocks expectation wasn't working as I expected last week having refactored a bit of code to include a constructor.</p>
<p>I wanted to include the Rhino Mocks source code in our solution before and after the refactoring and step through the code to see what was different in the way the expectations were being setup.</p>
<p>My initial thought was that I could just check out the repository again in another folder and then include the Rhino Mocks source code there and step through it but unfortunately we have all the projects set up to deploy to IIS so Visual Studio wanted me to adjust all those settings in order to load the solution in the new checkout location.</p>
<p>I probably could have gone and turned off that setting but it seemed a bit too much effort and I realised that I could easily use Git to help me solve the problem.</p>
<p>I took a patch of the changes I'd made and then reverted the code before checking it into a local Git repository.</p>
<p>I updated the solution to include the <a href="http://www.ayende.com/projects/rhino-mocks.aspx">Rhino Mocks</a> code and then created a branch called 'refactoringChanges' so that I could then apply the patch that I'd created with my changes.</p>
<p>It was then really easy to switch back between the two branches and see the differences in the way that the Rhino Mocks was working internally.</p>
<p>The actual problem eventually turned out to be the way that the code calls Castle DynamicProxy but I didn't get the chance to look further into it – we had learnt enough to know how we could get around the problem.</p>
<p>I'm in the process of including the source code for all the 3rd party libraries that we use in the solution on a separate Git branch that I can switch to when I want to debug through that code.</p>
<p>Sometimes I end up having to close down Visual Studio and re-open the solution when I switch to and from that branch but apart from that it seems to work reasonably well so far.</p>
<img height="1" src="http://feeds.feedburner.com/~r/MarkNeedham/~4/OuYLhbigDSk" width="1"/></div>
    </content>
    <updated>2010-03-14T00:45:34Z</updated>
    <category term="Software Development"/>
    <category term="dscm"/>
    <category term="git"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.markhneedham.com/blog/2010/03/14/a-reminder-of-the-usefulness-of-git/</feedburner:origlink>
    <author>
      <name>Mark Needham</name>
    </author>
    <source>
      <id>http://www.markhneedham.com/blog</id>
      <link href="http://www.markhneedham.com/blog" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/MarkNeedham" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Thoughts on Software Development</subtitle>
      <title>Mark Needham</title>
      <updated>2010-03-15T01:04:09Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.markhneedham.com/blog/?p=2251</id>
    <link href="http://feedproxy.google.com/~r/MarkNeedham/~3/ycltlXE-kKY/" rel="alternate" type="text/html"/>
    <title>Preventing systematic errors: An example</title>
    <summary>James Shore has an interesting recent blog post where he describes some alternatives to over reliance on acceptance testing and one of the ideas that he describes is fixing the process whenever a bug is found in exploratory testing.
He describes two ways of preventing bugs from making it through to exploratory testing:

Make the bug impossible
Catch [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>James Shore has <a href="http://jamesshore.com/Blog/Alternatives-to-Acceptance-Testing.html">an interesting recent blog post where he describes some alternatives to over reliance on acceptance testing</a> and one of the ideas that he describes is fixing the process whenever a bug is found in exploratory testing.</p>
<p>He describes two ways of preventing bugs from making it through to exploratory testing:</p>
<ul>
<li>Make the bug impossible</li>
<li>Catch the bug automatically</li>
</ul>
<blockquote><p>
Sometimes we can prevent defects by changing the design of our system so that type of defect is impossible. For example, if find a defect that's caused by mismatch between UI field lengths and database field lengths, we might change our build to automatically generate the UI field lengths from database metadata.</p>
<p>When we can't make defects impossible, we try to catch them automatically, typically by improving our build or test suite. For example, we might create a test that looks at all of our UI field lengths and checks each one against the database.
</p></blockquote>
<p>We had an example of the latter this week around some code which loads rules out of a database and then tries to map those rules to classes in the code through use of reflection.</p>
<p>For example a rule might refer to a specific property on an object so if the name of the property in the database doesn't match the name of the property on the object then we end up with an exception.</p>
<p>This hadn't happened before because we hadn't been making many changes to the names of those properties and when we did people generally remembered that if they changed the object then they should change the database script as well.</p>
<p>Having that sort of manual step always seems a bit risky to me since it's prone to human error, so having worked out what was going on we wrote a couple of integration tests to ensure that every property in the database matched up with those in the code.</p>
<p>We couldn't completely eliminate this type of bug in this case because the business wanted to have the rules configurable on the fly via the database.</p>
<p>It perhaps seems quite obvious that we should look to write these types of tests to shorten the feedback loop and allow us to catch problems earlier than we otherwise would but it's easy to forget to do this so James' post provides a good reminder!</p>
<img height="1" src="http://feeds.feedburner.com/~r/MarkNeedham/~4/ycltlXE-kKY" width="1"/></div>
    </content>
    <updated>2010-03-13T23:26:23Z</updated>
    <category term="Testing"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.markhneedham.com/blog/2010/03/13/preventing-systematic-errors-an-example/</feedburner:origlink>
    <author>
      <name>Mark Needham</name>
    </author>
    <source>
      <id>http://www.markhneedham.com/blog</id>
      <link href="http://www.markhneedham.com/blog" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/MarkNeedham" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Thoughts on Software Development</subtitle>
      <title>Mark Needham</title>
      <updated>2010-03-15T01:04:09Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-US">
    <id>163493:1540691:7006068</id>
    <link href="http://chad.wathington.com/blog/2010/3/13/me-on-dzone.html" rel="alternate" type="text/html"/>
    <title>Me on DZone</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Talking about our ALM tool suite, our pratices, and dogmatism.</p></div>
    </summary>
    <updated>2010-03-13T20:32:51Z</updated>
    <category term="agile"/>
    <category term="product development"/>
    <category term="product management"/>
    <author>
      <name>Chad Wathington</name>
    </author>
    <source>
      <id>http://chad.wathington.com/blog/</id>
      <link href="http://chad.wathington.com/blog/" rel="alternate" type="text/html"/>
      <link href="http://chad.wathington.com/blog/rss.xml" rel="self" type="application/rss+xml"/>
      <rights>Chad Wathington</rights>
      <subtitle>Chad Wathington's blog on Tech and Society</subtitle>
      <title>Tech Kindred</title>
      <updated>2010-03-16T05:02:24Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://jimbarritt.com/non-random/?p=362</id>
    <link href="http://jimbarritt.com/non-random/2010/03/13/rest-client-plugin-in-intellij/" rel="alternate" type="text/html"/>
    <title>REST client plugin in IntelliJ</title>
    <summary>Was just browsing the plugins and found this one which is looking good.
REST Client plugin
It was also available from the plugins list in the settings.</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Was just browsing the plugins and found this one which is looking good.</p>
<p><a href="http://plugins.intellij.net/plugin/?idea&amp;id=2200">REST Client plugin</a></p>
<p>It was also available from the plugins list in the settings.</p>
<div class="wp-caption alignnone" id="attachment_363" style="width: 661px;"><img alt="Rest Client intellij plugin screenshot" class="size-full wp-image-363" height="598" src="http://jimbarritt.com/non-random/wp-content/uploads/2010/03/RESTCLIENT.jpg" title="RESTCLIENT" width="651"/><p class="wp-caption-text">Rest Client intellij plugin screenshot</p></div>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fjimbarritt.com%2Fnon-random%2F2010%2F03%2F13%2Frest-client-plugin-in-intellij%2F&amp;linkname=REST%20client%20plugin%20in%20IntelliJ"><img alt="Share/Bookmark" height="24" src="http://jimbarritt.com/non-random/wp-content/plugins/add-to-any/share_save_256_24.png" width="256"/></a></div>
    </content>
    <updated>2010-03-13T11:15:34Z</updated>
    <category term="code"/>
    <category term="http"/>
    <category term="ides"/>
    <category term="thoughtblog"/>
    <author>
      <name>Jim Barritt</name>
    </author>
    <source>
      <id>http://jimbarritt.com/non-random</id>
      <link href="http://jimbarritt.com/non-random/category/thoughtblog/feed/" rel="self" type="application/atom+xml"/>
      <link href="http://jimbarritt.com/non-random" rel="alternate" type="text/html"/>
      <subtitle>adventures in code</subtitle>
      <title>non-random ramble » thoughtblog</title>
      <updated>2010-03-13T12:03:33Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://del.icio.us/brunns#2010-03-12</id>
    <link href="http://feedproxy.google.com/~r/SmallValuesOfCool/~3/BBrvGBHMiwY/brunns" rel="alternate" type="text/html"/>
    <title>Links for 2010-03-12 [del.icio.us]</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><ul>
<li><a href="http://www.kryogenix.org/days/2010/03/11/not-a-lawyer-any-more">Not a lawyer any more</a></li>
<li><a href="http://www.technologyreview.com/blog/arxiv/24917/?ref=rss">Orange Dwarf Star Set to Smash Into The Solar System</a><br/>
Duck!</li>
<li><a href="http://www.guardian.co.uk/world/2010/mar/12/memory-tests-gender-male">Absent-mindedness is a middle-aged male problem, research shows</a><br/>
Not just me, then.</li>
</ul></div>
    </summary>
    <updated>2010-03-13T08:00:00Z</updated><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://del.icio.us/brunns#2010-03-12</feedburner:origlink>
    <source>
      <id>http://www.brunningonline.net/simon/blog/</id>
      <author>
        <name>Simon Brunning</name>
        <email>simon.brunning+smallvaluescomment@gmail.com</email>
      </author>
      <link href="http://www.brunningonline.net/simon/blog/" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/SmallValuesOfCool" rel="self" type="application/rss+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <rights>Copyright 2010</rights>
      <subtitle>Simon Brunning - stuff that I find interesting</subtitle>
      <title>Small Values of Cool</title>
      <updated>2008-10-08T13:18:28Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.iamhukai.com/?p=135</id>
    <link href="http://www.iamhukai.com/?p=135" rel="alternate" type="text/html"/>
    <title>QA需要写程序么？</title>
    <summary>之前和未来的ThoughtWorker们讨论时，有人问我，测试人员需要写程序么？在我的理解里，一名QA的工作职责至少包括下面几个部分：
探索性测试： 通过测试来同时了解系统，设计对系统的测试以及执行测试。
系统分析：能够综合考虑所面临的问题领域和所编写应用类型来制定验收策略，
追踪问题：有能力在Bug出现时，不断的最小化重现缺陷的环境、步步逼近缺陷, 向开发人员提交高质量的缺陷单。
这里似乎没有编程什么事儿，考虑这样一个Console程序：
启动时读取XML格式的配置文件，以及CSV格式的输入文件，处理完毕输出console.log和CSV文件。
在测试时，作为一名QA：
你会不会尝试用XML编辑器先打开这个文件，然后再启动应用，看看应用能否正常启动？
你会不会尝试用Control+C, 资源管理器，进程管理器，Console上的关闭按钮分别关闭程序，并观察console.log？
你是否了解&lt;?xml version=”1.0″ encoding=”UTF-8″ ?&gt;和空的XML文件有什么不同？
你是否了解&lt;bla/&gt;和&lt;bla&gt;&lt;/bla&gt;有什么不同？
那么你需要学习什么：
你需要了解Windows文件系统的排它锁以及unix系统的共享锁
你需要学习Windows/Unix的进程管理
你需要一点点关于XML的常识
如果你在测试Web应用时，输入了一段文字后，点击按钮，按钮停止工作，你在提交缺陷前，有没有
更换另一浏览器？
更换同一浏览器的不同版本？
重新载入页面，输入不同的文字？
这些又有什么区别？
上面的测试方法和编程本身没有太大的关系，但是需要对计算机的工作原理，进程的工作原理，特定平台的应用的特性，网络的工作原理有足够的认识。而编写程序，就我看来是通常是驱动一个人完成上述积累最便捷，快速，有效的方法。
除非你不想成为一名优秀的，在市场里具有强大核心竞争力的QA（对薪水一个羞涩、隐晦的说法），否则我找不出有任何理由，QA可以不学习，不精通编程的。
不要把角色和职业搞混了，QA可能只是你众多角色中的一个。</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>之前和未来的ThoughtWorker们讨论时，有人问我，测试人员需要写程序么？在我的理解里，一名QA的工作职责至少包括下面几个部分：</p>
<p><a href="http://en.wikipedia.org/wiki/Exploratory_testing">探索性测试</a>： 通过测试来同时了解系统，设计对系统的测试以及执行测试。</p>
<p>系统分析：能够综合考虑所面临的问题领域和所编写应用类型来制定验收策略，</p>
<p>追踪问题：有能力在Bug出现时，不断的最小化重现缺陷的环境、步步逼近缺陷, 向开发人员提交高质量的缺陷单。</p>
<p>这里似乎没有编程什么事儿，考虑这样一个Console程序：</p>
<blockquote><p>启动时读取XML格式的配置文件，以及CSV格式的输入文件，处理完毕输出console.log和CSV文件。</p></blockquote>
<p>在测试时，作为一名QA：</p>
<blockquote><p>你会不会尝试用XML编辑器先打开这个文件，然后再启动应用，看看应用能否正常启动？</p>
<p>你会不会尝试用Control+C, 资源管理器，进程管理器，Console上的关闭按钮分别关闭程序，并观察console.log？</p>
<p>你是否了解&lt;?xml version=”1.0″ encoding=”UTF-8″ ?&gt;和空的XML文件有什么不同？</p>
<p>你是否了解&lt;bla/&gt;和&lt;bla&gt;&lt;/bla&gt;有什么不同？</p></blockquote>
<p>那么你需要学习什么：</p>
<blockquote><p>你需要了解Windows文件系统的排它锁以及unix系统的共享锁</p>
<p>你需要学习Windows/Unix的进程管理</p>
<p>你需要一点点关于XML的常识</p></blockquote>
<p>如果你在测试Web应用时，输入了一段文字后，点击按钮，按钮停止工作，你在提交缺陷前，有没有</p>
<blockquote><p>更换另一浏览器？</p>
<p>更换同一浏览器的不同版本？</p>
<p>重新载入页面，输入不同的文字？</p></blockquote>
<p>这些又有什么区别？</p>
<p>上面的测试方法和编程本身没有太大的关系，但是需要对计算机的工作原理，进程的工作原理，特定平台的应用的特性，网络的工作原理有足够的认识。<span style="color: #666699;"><strong>而编写程序，就我看来是通常是驱动一个人完成上述积累最便捷，快速，有效的方法。</strong></span></p>
<p>除非你不想成为一名优秀的，在市场里具有强大核心竞争力的QA（对薪水一个羞涩、隐晦的说法），否则我找不出有任何理由，QA可以不学习，不精通编程的。</p>
<p>不要把角色和职业搞混了，QA可能只是你众多角色中的一个。</p></div>
    </content>
    <updated>2010-03-13T03:27:07Z</updated>
    <category term="Uncategorized"/>
    <author>
      <name>我是胡凯</name>
    </author>
    <source>
      <id>http://www.iamhukai.com</id>
      <link href="http://www.iamhukai.com/?feed=rss2" rel="self" type="application/atom+xml"/>
      <link href="http://www.iamhukai.com" rel="alternate" type="text/html"/>
      <subtitle>多研究些问题，少谈些主义</subtitle>
      <title>I am Hu Kai</title>
      <updated>2010-03-13T04:00:44Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-6354510176298460211.post-2411905716933499055</id>
    <link href="http://marjoriepries.blogspot.com/feeds/2411905716933499055/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="http://marjoriepries.blogspot.com/2010/03/commenting-on-sumeet.html#comment-form" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/6354510176298460211/posts/default/2411905716933499055" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/6354510176298460211/posts/default/2411905716933499055" rel="self" type="application/atom+xml"/>
    <link href="http://marjoriepries.blogspot.com/2010/03/commenting-on-sumeet.html" rel="alternate" type="text/html"/>
    <title>Enterprises - Is too much experience a good thing?</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">In a recent blog post, <a href="http://www.learninggeneralist.com/2010/03/innovation-in-enterprise-is-too-much.html" target="blank">Innovation in the Enterprise</a>, my friend Sumeet Moghe raised the question, "Is too much experience a good thing?" He speculates that "...increasing experience in a company eventually stifle[s] innovation".<br/><br/>I agree the observation is valid; established enterprises are generally less innovative, relatively speaking, than start-ups. But is the general experience level of the employees to blame or is it a more complex question of the overall structure and culture of the enterprise? <br/><br/>Inertia, the preference to not change, is a powerful driving force in people. If there are 14 reasons to do something and 1 reason not to do it, it generally won't get done. This is partly explained by a principle that Robert Cialdini talks about in his "<a href="http://www.amazon.com/Influence-Psychology-Persuasion-Business-Essentials/dp/006124189X/ref=reader_auth_dp" target="blank">Influence</a>" book -- people are conditioned in early childhood to be wary of taking risks. They learn this from burning their hands, hitting their heads on or falling from tables, etc. So later in life, they are afraid to do something new, even if there is no risk involved. <br/><br/>The desire to reduce complexity is another factor that drives people to inertia. Faced with too many choices, or choices where the outcomes are difficult to evaluate, people tend to make no choice and stick with the status quo or default option. <em>(You can read more about this in <a href="http://www.amazon.com/Nudge-Improving-Decisions-Health-Happiness/dp/014311526X/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1268342325&amp;sr=1-1" target="blank">Nudge</a> by Thaler and Sunstein.)</em> <br/><br/>But there are many examples especially from music and art, that demonstrate that experience can deepen creativity. Consider the later symphonies by Mozart, Beethoven's late period string quartets, or the late works of Picasso, including that iconic sculpture in Chicago. On the other hand, certain studies indicate that some categories of creative thought, science and poetry for example, tend to peak early in life. Why?<br/><br/>A Wall Street Journal article <em><a href="http://online.wsj.com/article/SB10001424052748703444804575071573334216604.html" target="blank">"Fleeting youth, Fading Creativity"</a></em> takes a look at the field of academic science and, while citing many examples of young scientists who made breakthrough contributions, it also questions whether the structure of that industry discourages creativity in older scientists. <br/><br/>That raises a related question. Does the industry tend toward those structures because older scientists have lost their creativity or does the industry structure drive the creativity out of scientists?<br/><br/>But we are losing focus here. Sumeet's original question was about the nature of the enterprise. What causes an enterprise as a whole, as the sum of its people, to become less innovative over time? Even if the current staff is skewed toward younger people, as a company grows and acquires recognition, it tends to become less innovative.<br/><br/>Another friend would attribute this to the "monkey-butt" theory. As a monkey climbs higher in the tree, its butt gets more exposed and he feels the need to cover it. As a company grows, it establishes layers and divisions of management to handle operations and external relationships. The layers and divisions process ideas up to a board or similar small body of decision-makers. Each layer or division is another monkey in the tree looking to avoid the embarassment of a bad move. <br/><br/>Yet, in the field of applied science (consumer products) there are examples of enterprises that consistently innovated for long periods of their existence, usually driven by one or a few influential leaders who deliberately set up an innovating culture. One of these is 3M which for a long time had a "15 Percent Rule"; an employee was allowed to spend up to 15% of their paid time on independent projects of their own choosing. And another famous example is Xerox Parc. <br/><br/><em>(<a href="http://www.youtube.com/watch?v=amdONcqQvnU" target="blank">Click here</a> for a long video about creativity factors at Xerox Parc.)</em><br/><br/>But those firms are outliers. Most organizations, it seems to me, reach such a size and position in their market that their primary objective becomes "defend the status quo". <br/><br/>They have passed the start-up phase thanks to their "guaranteed product or process or method for success." Their brand grows and most operational resources get devoted to selling the "guaranteed product or process or method." This compells them to seek out and train employees who are excited to be associated with the "guaranteed product or process or method." A culture evolves that believes in and defends this one sure thing. Innovation loses momentum.<br/><br/>A company can't break out of this dependency on the status quo unless it is willing to set up and fund independent internal ventures as 3M did. In effect, the enterprise must be willing to recognize and fund its own competition from within.<div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/6354510176298460211-2411905716933499055?l=marjoriepries.blogspot.com" width="1"/></div></div>
    </content>
    <updated>2010-03-12T21:41:10Z</updated>
    <published>2010-03-11T22:43:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="innovation"/>
    <author>
      <name>Marjorie Pries</name>
      <email>noreply@blogger.com</email>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-6354510176298460211</id>
      <author>
        <name>Marjorie Pries</name>
        <email>noreply@blogger.com</email>
      </author>
      <link href="http://marjoriepries.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.blogger.com/feeds/6354510176298460211/posts/default" rel="self" type="application/atom+xml"/>
      <link href="http://marjoriepries.blogspot.com/" rel="alternate" type="text/html"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://www.blogger.com/feeds/6354510176298460211/posts/default?start-index=26&amp;max-results=25" rel="next" type="application/atom+xml"/>
      <title>Marjorie Pries: Don't believe everything you think</title>
      <updated>2010-03-12T21:44:17Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-US">
    <id>tag:gigix.thoughtworkers.org,2010-03-12:1029</id>
    <link href="http://gigix.thoughtworkers.org/2010/3/12/refactoring-in-turing-press" rel="alternate" type="text/html"/>
    <title xml:lang="en-US">《重构》再版，欲购从速</title>
    <content type="xhtml" xml:lang="en-US"><div xmlns="http://www.w3.org/1999/xhtml"><p>首先，不要恐慌。这不是《重构》第二版。只是由于某种愚蠢的原因，从前的那个中文版已经买不到了。现在，它换了个书皮，让需要的人能买到。仅此而已。</p>


	<p>刘江兄写了一个 <a href="http://blog.csdn.net/turingbook/archive/2010/03/11/5366962.aspx">煽情的宣传</a> 。“从一个光荣的大学辍学少年（步乔布斯、盖茨后尘？）成长为ThoughtWorks的资深咨询师，Martin Fowler的同事。”嗯，很好的阶段性总结。</p>


	<p>（有时候我很怀疑自己做的一切是否真的有意义。如果“大家”真的会学习的话，为什么《重构》出版那么多年以后还有那么多烂代码存在──当然，如果“大家”真的会学习的话，为什么还有战争？）</p>


	<p>时间，才是最神奇的重构工具。这句话，也很好，很隽永。</p>


	<p><a href="http://www.china-pub.com/196374"><img height="251px" src="http://www.turingbook.com/Data/Book/f38697a7-538c-4e1a-9a82-919433275d82/Cover/CoverBig.jpg" width="200px"/></a></p></div>
    </content>
    <updated>2010-03-12T16:02:32Z</updated>
    <published>2010-03-12T15:49:00Z</published>
    <author>
      <name>gigix</name>
    </author>
    <source>
      <id>tag:gigix.thoughtworkers.org,2010:mephisto/</id>
      <link href="http://gigix.thoughtworkers.org/feed/rss2.xml" rel="self" type="application/atom+xml"/>
      <link href="http://gigix.thoughtworkers.org/" rel="alternate" type="text/html"/>
      <title xml:lang="en-US">透明思考 - Thoughts</title>
      <updated>2010-03-12T16:02:32Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-US">
    <id>tag:gigix.thoughtworkers.org,2010-03-12:1028</id>
    <link href="http://gigix.thoughtworkers.org/2010/3/12/large-scale-agile-with-toyota-approach" rel="alternate" type="text/html"/>
    <title xml:lang="en-US">借鉴丰田方法对大型软件组织进行敏捷改造（上）</title>
    <content type="xhtml" xml:lang="en-US"><div xmlns="http://www.w3.org/1999/xhtml"><p><span class="caps">QWS</span>是一款电信交换机产品，其软件部分用C语言开发。经过长期的发展演化，当本文所述的咨询项目开始时，QWS的总体代码量已经超过2000万行，代码库体积超过4GB。本咨询项目所涉及的版本需要新开发的代码量约90万行。</p>


	<p><span class="caps">QWS</span>的版本交付团队大致由90名左右开发人员和30名左右测试人员组成。这支交付团队又按特性和模块划分为6个特性团队和2个任务团队，共计8个子项目组。每个项目组分别有一个SVN工作分支，项目组成员将代码提交到分支，项目经理再负责将分支代码合并到主干。</p>


	<p>在ThoughtWorks顾问组进入该团队之时，这支多年沿用CMM方法的团队正在自行尝试敏捷方法，刚刚开始第一个为期3周的迭代。但这第一个迭代远非一帆风顺。一方面，由于团队从来没有迭代交付的习惯，开发人员在编码阶段忽视质量，导致提交到SVN的代码有时甚至不能编译，即使编译出软件大包也存在严重功能缺陷，无法进行测试；另一方面，由于团队成员对SVN缺乏了解，多个分支的配置管理遇到了极大的困难。</p>


	<p>就在这样一种混乱的状态中，由3名ThoughtWorks咨询师组成的顾问组进驻了这支交付团队，开始对其进行为期4个月的敏捷改造。在项目进展中，我们大量借鉴了源自丰田的精益思想，最终取得了显著的成效。</p>


	<p>（ <a href="http://blog.csdn.net/gigix/archive/2010/03/11/5371464.aspx">阅读全文</a> ）</p></div>
    </content>
    <updated>2010-03-12T12:04:26Z</updated>
    <published>2010-03-12T11:55:00Z</published>
    <author>
      <name>gigix</name>
    </author>
    <source>
      <id>tag:gigix.thoughtworkers.org,2010:mephisto/</id>
      <link href="http://gigix.thoughtworkers.org/feed/rss2.xml" rel="self" type="application/atom+xml"/>
      <link href="http://gigix.thoughtworkers.org/" rel="alternate" type="text/html"/>
      <title xml:lang="en-US">透明思考 - Thoughts</title>
      <updated>2010-03-12T16:02:32Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.magpiebrain.com/?p=826</id>
    <link href="http://feedproxy.google.com/~r/Magpiebrain/~3/Oruf8LR1GcY/" rel="alternate" type="text/html"/>
    <title>My Talk at QCon SF 2009</title>
    <summary>The talk I did at QCon SF 2009 is now available at infoq. Only an MP3 download is available, otherwise you’ll have to stream it from the site – but you’ll be missing a lot, as the slides are better than hearing me drone on.</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>The talk I did at QCon SF 2009 is <a href="http://www.infoq.com/presentations/navigating-agile-rapids" title="Navigating The Rapids:Real-World Lessons in Adopting Agile">now available</a> at infoq. Only an MP3 download is available, otherwise you’ll have to stream it from the site – but you’ll be missing a lot, as the slides are better than hearing me drone on.</p>
</div>
    </content>
    <updated>2010-03-12T10:40:15Z</updated>
    <category term="Agile"/>
    <category term="presentations"/>
    <category term="qcon"/>
    <category term="qconsf"/>
    <category term="video"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.magpiebrain.com/2010/03/12/my-talk-at-qcon-sf-2009/</feedburner:origlink>
    <author>
      <name>Sam Newman</name>
    </author>
    <source>
      <id>http://www.magpiebrain.com</id>
      <link href="http://www.magpiebrain.com" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/Magpiebrain" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>The blog of Sam Newman</subtitle>
      <title>Magpiebrain</title>
      <updated>2010-03-12T11:00:41Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.dancingmango.com/blog/?p=857</id>
    <link href="http://feedproxy.google.com/~r/Dancingmango/~3/awKtdXl8IqQ/" rel="alternate" type="text/html"/>
    <title>The journey doesn’t end with the buy button</title>
    <summary>Take a look at this and tell me what information it conveys to you.  Look at the order status…

Dispatched.
So five days later when I ring up Laskys to find out what has happened to my product I’m told “we’re sorry, the product is out of stock.  Would you like another similar product?”  I’m not exactly [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Take a look at this and tell me what information it conveys to you.  Look at the order status…<br/>
<a href="http://www.dancingmango.com/blog/wp-content/uploads/2010/03/laskys.jpg"><img alt="" class="aligncenter size-medium wp-image-858" height="36" src="http://www.dancingmango.com/blog/wp-content/uploads/2010/03/laskys-300x36.jpg" title="Laskys product confirmation" width="300"/></a></p>
<p>Dispatched.</p>
<p>So five days later when I ring up <a href="http://www.laskys.com/" target="_blank">Laskys</a> to find out what has happened to my product I’m told “we’re sorry, the product is out of stock.  Would you like another similar product?”  I’m not exactly a happy chappy to find this out five days after the order has been placed. I’ve been to ‘my account’ to track my order and it tells me that the order has (click on the help icon) “been processed and either has a delivery date or has been delivered”.  Well no actually, it is out of stock and your eCommerce system hasn’t accommodated that scenario in the customer experience.  Sorry Laskys, you lied to me.</p>
<p>“We did actually send you an email on the 8th of March to let you know this”.  So I went back through my mailbox and indeed they had sent me a mail.  I use gmail.  The mail was unread, but I get so many mails I don’t always open them, especially as gmail gives you the title and the first line of the mail.  The mail in question from Customer Service was titled “Your Order” and the following first line; “Thank you for placing an order with Laskys. TheSEBO X4 EXTRA  on order 025″.  nothing there to suggest that it was out of stock.  Just a generic subject and first line of copy.  They had taken my phone number as part of the process; no-one thought to ring me.  Overall a poor experience.  I won’t be buying from Laskys again and I suggest you don’t either.</p>
<p>There’s a lesson here.  It is easy to focus upon the shiny stuff, to get customers converting, clicking on that buy button.  But if the post-buy button experience is lacking; if you haven’t factored in <em>operational excellence</em> into your process, in the long run it is likely to cost you.</p>
<img height="1" src="http://feeds.feedburner.com/~r/Dancingmango/~4/awKtdXl8IqQ" width="1"/></div>
    </content>
    <updated>2010-03-12T10:28:20Z</updated>
    <category term="Customer Experience"/>
    <category term="eCommerce"/>
    <category term="shopping"/>
    <category term="usability"/>
    <category term="laskys"/>
    <category term="conveys"/>
    <category term="button"/>
    <category term="information"/>
    <category term="title"/>
    <category term="product"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.dancingmango.com/blog/2010/03/12/the-journey-doesnt-end-with-the-buy-button/</feedburner:origlink>
    <author>
      <name>marc</name>
    </author>
    <source>
      <id>http://www.dancingmango.com/blog</id>
      <link href="http://www.dancingmango.com/blog" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/Dancingmango" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>It's all about the human experience</subtitle>
      <title>dancingmango</title>
      <updated>2010-03-13T02:03:54Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://del.icio.us/brunns#2010-03-11</id>
    <link href="http://feedproxy.google.com/~r/SmallValuesOfCool/~3/crXlnbsQMPg/brunns" rel="alternate" type="text/html"/>
    <title>Links for 2010-03-11 [del.icio.us]</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><ul>
<li><a href="http://grognardia.blogspot.com/2009/01/travelling-man.html">Travel(l)ing Man</a><br/>
Oh yes.</li>
<li><a href="http://grognardia.blogspot.com/2009/12/retrospective-champions.html">Retrospective: Champions</a></li>
<li><a href="http://www.escapistmagazine.com/articles/view/columns/days-of-high-adventure/7185-Behind-the-Masks-of-Nyarlathotep-Larry-DiTillio">Behind the Masks of Nyarlathotep: Larry DiTillio</a></li>
<li><a href="http://grognardia.blogspot.com/2009/09/retrospective-masks-of-nyarlathotep.html">Retrospective: Masks of Nyarlathotep</a></li>
<li><a href="http://grognardia.blogspot.com/2009/09/retrospective-bushido.html">Retrospective: Bushido</a></li>
<li><a href="http://www.rabbitmq.com/">RabbitMQ</a></li>
<li><a href="http://thomas.broxrost.com/2008/08/21/persistent-django-on-amazon-ec2-and-ebs-the-easy-way/">Django on Amazon EC2</a></li>
</ul></div>
    </summary>
    <updated>2010-03-12T08:00:00Z</updated><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://del.icio.us/brunns#2010-03-11</feedburner:origlink>
    <source>
      <id>http://www.brunningonline.net/simon/blog/</id>
      <author>
        <name>Simon Brunning</name>
        <email>simon.brunning+smallvaluescomment@gmail.com</email>
      </author>
      <link href="http://www.brunningonline.net/simon/blog/" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/SmallValuesOfCool" rel="self" type="application/rss+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <rights>Copyright 2010</rights>
      <subtitle>Simon Brunning - stuff that I find interesting</subtitle>
      <title>Small Values of Cool</title>
      <updated>2008-10-08T13:18:28Z</updated>
    </source>
  </entry>

  <entry>
    <id>http://betarelease.github.com/2010/03/12/prepare-to-be-a-trainer</id>
    <link href="http://betarelease.github.com/2010/03/12/prepare-to-be-a-trainer.html" rel="alternate" type="text/html"/>
    <title>Preparing to be a trainer</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><h1>Preparing to be a trainer</h1>
<p>Preparing to be a trainer is more of a mental activity than physical. To be one you would want to observe one and learn how they do it. I had the opportunity of being trained by a set of great trainers/speakers and also working them to understand how they prepared to be a trainer. Mostly it is about being aware of the responsibility. It takes time to get a feel for the amount of work that goes into being a trainer. To facilitate this we started by studying the course material that was already available(In a sense I was lucky that there was so much refined course material available that I did not need to invest any time in design the course. Designing a course is a major undertaking and can be done only after much experience [#feedback]).</p>
<p>Another thing you must do is actually be a co-trainer/teaching assistant at a training session to get a feel of the mechanics of it all.(What gets overlooked is the fact that managing time/schedule and training content is harder than it appears.) To prepare to be such a person one needs to know the complete training course. To be a developer trainer I went through the exercise of reading all the material and also solving and reasoning all the examples for the course. At times it also helps to have multiple solutions at hand. In collaboration with other trainers and trainees we have managed to have a repository of such sample solutions that we are prepared with to hand out to trainees.</p>
<p>Once you have a grip on the course content you need to plan and replay the plan of how the content will be presented. Pairing on course content tremendously helps. In case of vast curriculum it helps to divide responsibility between the pair to deliver certain topics based on experience, enthusiasm and freshness of the trainer. Making a plan of the day for every half hour slot helps get a feel of timeliness as well as helps focus on delivering the most important message of the session effectively. Rehearsing all this with a pair is greatly useful. We had the opportunity to rehearse this training with the smaller group to time ourselves as well as refine delivery of content. Understanding what messages are to be delivering during the session and what content is to be learnt after class/further exercise helps divide the content and reduce course load.</p>
<p>There is a lot of physical activity involved too. To enhance retention and recollection it may be a good idea to prepare homework/extra work problems. Some students really gain a lot from working on these in their spare time. A trick that also helps retention is ‘rinse and repeat’ – We provided handouts of the most important messages of the session and reviewed sessions at the end and few days later.</p>
<p>Preparing also needs to consider the amount of stationary required, hardware required, accessories such as timers, props and power availability at the venue.[#venue]</p>
<p>Training is a lot of hard work. Do not jump in if you don’t thing 12 hour days + dinner + a night out are not something you can take. Not to mention activities that require you to be available on a weekend.</p>
<ol>
	<li>Prepare course content</li>
	<li>Plan out each day</li>
	<li>Rehearse</li>
	<li>Ensure retention by way of handouts or reviews</li>
	<li>Prepare the venue to suit the training</li>
</ol></div>
    </content>
    <updated>2010-03-12T08:00:00Z</updated>
    <source>
      <id>http://betarelease.github.com/</id>
      <author>
        <name>Sudhindra Rao</name>
        <email>srrao2k (at) gmail.com</email>
      </author>
      <link href="http://betarelease.github.com/atom.xml" rel="self" type="application/atom+xml"/>
      <link href="http://betarelease.github.com/" rel="alternate" type="text/html"/>
      <title>Sudhindra Rao</title>
      <updated>2010-03-12T19:54:00Z</updated>
    </source>
  </entry>

  <entry>
    <id>http://betarelease.github.com/2010/03/12/no-such-file-to-load-rubygems</id>
    <link href="http://betarelease.github.com/2010/03/12/no-such-file-to-load-rubygems.html" rel="alternate" type="text/html"/>
    <title>no such file to load --rubygems</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><h1>no such file to load —rubygems</h1>
<p>While working on my mac and trying to use giternal I ran into ‘no such file to load —rubygems’. While I had been using ruby apps on the machine for a while, without any issues and with all the installed gems, this seemed weird.</p>
<p>I tried using the irb and check if</p>
<p>irb&gt; require ‘rubygems’</p>
<p>would work. But I got the same error. I was using the default mac version of the ruby installation that is installed at ‘/System/Library/Frameworks/Ruby.framework…..’ and did verify that rubygems was installed and that rubygems.rb was also present.</p>
<p>On further investigation I found that the default ruby that was run on the command line was 1.8.7 when I expected 1.8.6. <br/>
It appears that my path contained ‘/opt/local/bin’ before ‘/usr/bin’ which made the 1.8.7 version of ruby default and thus clobbered all by 1.8.6 settings and lost rubygems.</p>
<p>To fix this I moved ‘opt/local/bin’ to be after ‘/usr/bin’ in my $<span class="caps">PATH</span> and voila everything works again.</p>
<p>I have also been meaning to try <span class="caps">RVM</span> – maybe its time to give it a shot since my personal projects are on 1.8.7 and I have jruby as well as 1.8.6 installed on my mac.</p></div>
    </content>
    <updated>2010-03-12T08:00:00Z</updated>
    <source>
      <id>http://betarelease.github.com/</id>
      <author>
        <name>Sudhindra Rao</name>
        <email>srrao2k (at) gmail.com</email>
      </author>
      <link href="http://betarelease.github.com/atom.xml" rel="self" type="application/atom+xml"/>
      <link href="http://betarelease.github.com/" rel="alternate" type="text/html"/>
      <title>Sudhindra Rao</title>
      <updated>2010-03-12T19:54:00Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://dahliabock.wordpress.com/?p=369</id>
    <link href="http://dahliabock.wordpress.com/2010/03/11/book-review-getting-real-the-smarter-faster-easier-way-to-build-a-successful-web-application/" rel="alternate" type="text/html"/>
    <title>dlbock</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Getting Real: The smarter, faster, easier way to build a successful web application by Jason Fried (@ 37signals.com)
It was a little annoying that I only found out about this book 3 days ago considering that it came out about 4 years ago. Granted I was still an ignorant college kid trying to graduate back then, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&amp;blog=4589287&amp;post=369&amp;subd=dahliabock&amp;ref=&amp;feed=1"/></div>
    </summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p><a href="http://gettingreal.37signals.com/index.php" target="_blank"><strong>Getting Real: The smarter, faster, easier way to build a successful web application</strong></a> by Jason Fried (@ <a href="http://37signals.com/" target="_blank">37signals.com</a>)</p>
<p>It was a little annoying that I only found out about this book 3 days ago considering that it came out about 4 years ago. Granted I was still an ignorant college kid trying to graduate back then, it still doesn’t excuse the fact that I haven’t heard or read about it at all till now. I like how the tone of the book is extremely direct and in-your-face. The guys at 37signals talk about how they build software with as little people and resources as possible but are still able to produce stellar results, in terms of customer satisfaction, revenue generation and happy employees, just to name a few.</p>
<p>I have been privileged (or not, depending on how you see it) to have been on projects that have made many of the same mistakes that the book points out. Making mistakes is a good thing. The trick is to actually learn from them. Teams like the one at 37signals have figured out certain practices and behaviors that work for them. Reading about them has been a breath of fresh air, that there are people out there who care about what they do so much that they are bold enough to step out on a limb to take steps that others would deem foolish and even bolder to talk about them in public.</p>
<p>Here are some of my favorite parts.</p>
<p><em>We believe software is too complex. Too many features, too  many buttons, too much to learn. Our products do less than  the competition — intentionally. We build products that work  smarter, feel better, allow you to do things your way, and are  easier to use.</em></p>
<p><em>Don’t get huffy if you read some of our advice and it reminds you of something you read about already on so and so’s weblog or in some book published 20 years ago. It’s definitely possible. These techniques are not at all exclusive to 37signals. We’re just telling you how we work and what’s been successful for us.</em></p>
<p><em><strong>Build Less</strong></em><br/>
<em>Solve the simple problems and leave the hairy, difficult, nasty problems to everyone else. Instead of oneupping, try one-downing. Instead of outdoing, try underdoing.</em></p>
<p><em><strong>Launch on time and on budget</strong><br/>
If you can’t fit everything in within the time and budget allotted then don’t expand the time and budget. Instead, pull back the scope. There’s always time to add stuff later — later is eternal, now is fleeting.</em></p>
<p><strong><em>Ignore Details Early On<br/>
</em></strong><em>Don’t worry about the size of your headline font in week one. You don’t need to nail that perfect shade of green in week two. You don’t need to move that “submit” button three pixels to the right in week three. Just get the stuff on the page for now. Then use it. Make sure it works. Later on you can adjust and perfect it.</em></p>
<p><strong><em>It’s a Problem When It’s a Problem</em><br/>
</strong><em>Do you really need to worry about scaling to 100,000 users today if it will take you two years to get there? Do you really have to hire eight programmers if you only need three today? Do you really need 12 top-of-the-line servers now if you can run on two for a year?</em></p>
<p><strong><em>Make Opinionated Software</em><br/>
</strong><em>Some people argue software should be agnostic. They say it’s arrogant for developers to limit features or ignore feature requests. They say software should always be as flexible as possible. We think that’s bullshit. The best software has a vision. The best software takes sides. When someone uses software, they’re not just looking for features, they’re looking for an approach. They’re looking for a vision. Decide what your vision is and run with it.</em></p>
<p><strong><em>Build half a product, not a half ass product<br/>
</em></strong><em>Beware of the “everything but the kitchen sink” approach to web app development. Throw in every decent idea that comes along and you’ll just wind up with a half-assed version of your product. What you really want to do is build half a product that kicks ass.</em></p>
<p><strong><em>Start with a No<br/>
</em></strong><em>Each time you say yes to a feature, you’re adopting a child. You have to take your baby through a whole chain of events (e.g. design, implementation, testing, etc.). And once that feature’s out there, you’re stuck with it. Just try to take a released feature away from customers and see how pissed off they get. Make each feature work hard to be implemented. Make each feature prove itself and show that it’s a survivor. It’s like “Fight Club.” You should only consider features if they’re willing to stand on the porch for three days waiting to be let in. </em>[This is probably my favorite part of the book]</p>
<p>It’s a very fast read. 16 chapters, 91 essays and each essay is never longer than a page scroll down. I blazed through 13 chapters in 2.5 days. I think this book ranks as one of my favorites next to <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" target="_blank">Uncle Bob’s Clean Code</a>.</p>
<p><em><br/>
</em></p>
<br/>  <a href="http://feeds.wordpress.com/1.0/gocomments/dahliabock.wordpress.com/369/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dahliabock.wordpress.com/369/"/></a> <a href="http://feeds.wordpress.com/1.0/godelicious/dahliabock.wordpress.com/369/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dahliabock.wordpress.com/369/"/></a> <a href="http://feeds.wordpress.com/1.0/gostumble/dahliabock.wordpress.com/369/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dahliabock.wordpress.com/369/"/></a> <a href="http://feeds.wordpress.com/1.0/godigg/dahliabock.wordpress.com/369/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dahliabock.wordpress.com/369/"/></a> <a href="http://feeds.wordpress.com/1.0/goreddit/dahliabock.wordpress.com/369/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dahliabock.wordpress.com/369/"/></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dahliabock.wordpress.com&amp;blog=4589287&amp;post=369&amp;subd=dahliabock&amp;ref=&amp;feed=1"/></div>
    </content>
    <updated>2010-03-12T03:39:17Z</updated>
    <category term="books"/>
    <author>
      <name>Dahlia Bock</name>
    </author>
    <source>
      <id>http://dahliabock.wordpress.com</id>
      <logo>http://www.gravatar.com/blavatar/1bcdecb66b684b9a3e8d1ca6e602c959?s=96&amp;d=http://s2.wp.com/i/buttonw-com.png</logo>
      <link href="http://dahliabock.wordpress.com/feed/" rel="self" type="application/atom+xml"/>
      <link href="http://dahliabock.wordpress.com" rel="alternate" type="text/html"/>
      <link href="http://dahliabock.wordpress.com/osd.xml" rel="search" type="application/opensearchdescription+xml"/>
      <link href="http://dahliabock.wordpress.com/?pushpress=hub" rel="hub" type="text/html"/>
      <title>Dahlia Bock</title>
      <updated>2010-03-12T04:04:09Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-8528631747209969303.post-1154925410981581299</id>
    <link href="http://docondev.blogspot.com/feeds/1154925410981581299/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="http://docondev.blogspot.com/2010/03/caution-metrics-change-behavior.html#comment-form" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default/1154925410981581299" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default/1154925410981581299" rel="self" type="application/atom+xml"/>
    <link href="http://docondev.blogspot.com/2010/03/caution-metrics-change-behavior.html" rel="alternate" type="text/html"/>
    <title>Caution: Metrics change behavior</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><h4>Measuring and reporting are important</h4><div class="left w50">I've often heard said, "That which you cannot measure, you cannot improve." And while I do believe this is a general truth, I think it fails to tell the entire story. It is not just about what we can measure, but what we actually do measure that is significant; "That which is reported, will improve."</div><div class="right w50"><br/><blockquote>What is not measurable, make measurable. -- Galileo Galilei 1564-1642.</blockquote></div><div style="clear: right; height: 45px;"/><h4>Measuring and reporting influence behavior</h4>Metrics give us feedback. Metrics show a measure of progress toward our goals. Metrics remind us what is most important. Visible metrics, ala <a href="http://www.agilealliance.org/show/733">Big Visible Charts</a>, help to focus the team on what is most important.<br/><br/><blockquote>...if I have quick access to key metrics every day, my creativity stays within certain bounds – my ideas all center on how to achieve our goals. -- <a href="http://www.paulallen.net/2006/10/10/domino-rally-business-models/">Paul B. Allen</a></blockquote><br/>Access to key metrics provides an individual or a team a quick means of assessing progress and focusing their minds on what is most important. These can be excellent tools for influencing a team toward a desired goal or level of performance.<br/><br/>But the outcome is not always what we intend.<br/><br/><h4>The Hawthorne Effect</h4>There is a now famous study that was done in the early 1900s. Hawthorne Works commissioned a study of the effects of ambient lighting on worker productivity. The results of the test were perplexing. Essentially, worker throughput seemed to increase despite the level of light. High, low, medium; with each change, throughput increased. Once the study was concluded, levels quickly fell back to "normal".<br/><br/>The are several criticisms of this particular study, but the phenomenon has been repeated under different circumstances since.<br/><br/>The conclusion; that which was measured, improved. Effectively, because people were aware their throughput was being measured, it increased. In similar studies, people's throughput increased when they were knowingly observed but received no guidance or feedback. So they <em>assumed</em> throughput was the objective.<br/><br/><h4>Rock On! Where is my plotter?</h4>So this is pretty awesome, huh? Just let people know you are watching them and their productivity will soar! Throw up a few charts and you've got yourself a high-functioning team.<br/><br/><h4>You wish</h4>So here's the rub. An increase in throughput is not necessarily a good thing.<br/><br/><h5>Why Not?</h5>Do you believe your employees are slackers?<br/>Do you think they lollygag about all morning, marking time until lunch and then perhaps featherbed it to 5pm before they skedaddle out the door?<br/><br/>If you do, then you have a significant problem. A problem that a few charts and some good old fashioned micro-management probably won't solve. But, hey, it is worth a try....<br/><br/><h4>Our employees suck less than that</h4>Good. So you have a reliable, forthright, responsible team of people. If this is the case, then you might do well to be a bit leery of easy increases in throughput. I'm not saying it is a bad thing, but that extra throughput had to originate somewhere. Perhaps it is less time spent in needless meetings. Perhaps it is better attention to priority items. If so...<br/><br/><blockquote class="green">Huzzah for metrics!<br/></blockquote><br/>BUT...<br/><br/><h4>You've been warned</h4>That which you measure and report will improve.<br/><br/>If what you track and report is one-sided, your results will be one-sided.<br/><br/>When you are on an agile team and all of your metrics are about velocity, you send a clear message to the team.<br/><br/><blockquote class="red">Go Faster! <span style="color: #999; font-size: x-small;">quality ain't all that important and value don't matter</span><br/></blockquote><br/><h4>Goodhart's Law</h4>Goodhart's Law is a principle first defined in 1975 in a paper by Charles Goodhart, chief economic advisor to the Bank of England. Goodhart's basic premise is that economic indicators made into targets for the purpose of conducting economic policy, thereby lose their ability to serve in the desired capacity.<br/><br/>More succinctly put - When a measure becomes a target, it ceases to be a good measure.<br/><br/>Goodhart's law is applicable to both economics and sociology. It is a proven fact (law) that when you take an indicator such as velocity and you make it a target, you thereby eliminate it as a valid indicator.<br/><br/><h4>Good Metrics</h4>Measure value, not throughput. How many of the high-value stories were delivered, regardless of points.<br/><br/>Focus on your customer's determination of value. How do your metrics tie directly to their single highest priority?<br/><br/>Study trends, not moments in time.<br/><br/>Use metrics as a diagnostic tool. When a problem is identified, devise one or two metrics that will help diagnose and monitor the health of the issue. When resolved, stop measuring.<br/><br/>Do not record or report metrics for reporting sake.<br/><br/>Do not set targets for your metrics.<br/><br/>If you must report velocity, report only team velocity.<div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/8528631747209969303-1154925410981581299?l=docondev.blogspot.com" width="1"/></div></div>
    </content>
    <updated>2010-03-12T01:21:23Z</updated>
    <published>2010-03-10T05:37:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="Development"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Teams"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Programming Practices"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Agile"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Metrics"/>
    <author>
      <name>DocOnDev</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/17064897772691908215</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-8528631747209969303</id>
      <author>
        <name>DocLogic</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/09149149882666714621</uri>
      </author>
      <link href="http://docondev.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default" rel="self" type="application/atom+xml"/>
      <link href="http://docondev.blogspot.com/" rel="alternate" type="text/html"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default?start-index=26&amp;max-results=25" rel="next" type="application/atom+xml"/>
      <subtitle>Michael Norton (doc) is a Development Manager living in Wadsworth, OH. Michael's experience covers a wide range of development topics. Michael declares expertise in no single language or methodology and is immediately suspicious of anyone who declares such expertise.</subtitle>
      <title>Doc On Dev</title>
      <updated>2010-03-15T01:40:13Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:typepad.com,2003:post-6a01156f76f3eb970c0120a9263553970b</id>
    <link href="http://www.apcjones.com/blog/2010/03/finelysliced-operations.html" rel="alternate" type="text/html"/>
    <link href="http://www.apcjones.com/blog/2010/03/finelysliced-operations.html" rel="replies" type="text/html"/>
    <title>Finely-Sliced Operations</title>
    <summary>Since the previous post, I've reading up more on the devops movement and found a few nice pieces, particularly Graham Bleach on internal borders. Thinking about borders within operations departments, I'm reminded of a recent client who operated with a...</summary>
    <content type="xhtml" xml:lang="en-US"><div xmlns="http://www.w3.org/1999/xhtml"><p>Since the previous post, I've reading up more on the devops movement and found a few nice pieces, particularly <a href="http://www.darkskills.org.uk/diary/index.php?wl_mode=more&amp;wl_eid=147">Graham Bleach on internal borders</a>.</p><p>Thinking about borders within operations departments, I'm reminded of a recent client who operated with a mind-blowing number of siloed operations teams.  Coming at it from the development side, working through a problem with the operations staff was like exploring a never-ending labyrinth of teams.  Every time I probed a little deeper, my contact would defer responsibility to another mysterious team, usually located somewhere distant, that owned a slightly lower level of the stack.  Once I tracked down a real person in the mysterious team, the same thing would happen again, and I would be left searching for another distant team.  It seemed like I would never actually get to the real hardware.  An unforeseen consequence of virtualization is that it allows someone to declare themselves in charge of a Virtual Machine, but not in charge of the host or guest operating systems nor the hardware itself - staggeringly unhelpful.</p><p>The genius of these extremely-finely-sliced organisations is that they provide innumerable cracks down which responsibility, ownership and useful work can fall.  If a team has a sufficiently narrow focus, it is almost certain that no problem will ever occur that falls cleanly within its boundaries, so there is no responsibility at all - a manager's dream.</p><p>One thing that encourages me a little bit is a recent trend for counting the number "engineers" in an organisation.  I think all technical staff are counted in this metric, though I'm not sure whether people are including managers and other IT staff who might not be hands on.  In his <a href="http://qconlondon.com/london-2010/presentation/Facebook:+Architecture+and+Design">QCon talk</a>, Aditya Agarwal was very proud of Facebook's metric of 1.1 million users per engineer, while <a href="http://qconlondon.com/london-2010/presentation/Building+Skype.+Learnings+from+almost+five+years+as+a+Skype+Architect">Andres Kütt</a> was similarly proud of Skype's 600,000 users per <em>employee</em>.  Note that Facebook is very open about its number of engineers but secretive about its number of <em>employees</em> - I have no idea why.  I think counting the total number of technical staff is useful because helps people look at the broader cost of running software - not just development or just operations.  Also, I hope in the long term these kinds of metrics will highlight the painful inefficiency of silos and barriers.</p></div>
    </content>
    <updated>2010-03-11T13:08:18Z</updated>
    <published>2010-03-11T13:05:46Z</published>
    <author>
      <name>Alistair Jones</name>
    </author>
    <source>
      <id>tag:typepad.com,2003:weblog-1866507</id>
      <link href="http://www.apcjones.com/blog/atom.xml" rel="self" type="application/atom+xml"/>
      <link href="http://hubbub.api.typepad.com/" rel="hub" type="text/html"/>
      <link href="http://www.apcjones.com/blog/" rel="alternate" type="text/html"/>
      <title>Alistair Jones Blog</title>
      <updated>2010-03-15T09:35:27Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:typepad.com,2003:post-6a01156f76f3eb970c0120a9213da5970b</id>
    <link href="http://www.apcjones.com/blog/2010/03/specialisation-without-silos.html" rel="alternate" type="text/html"/>
    <link href="http://www.apcjones.com/blog/2010/03/specialisation-without-silos.html" rel="replies" type="text/html"/>
    <title>Specialisation without Silos</title>
    <summary>I'm watching Michael Nygard's talk in the devops track at QCon. This is my first taste of the devops movement and it's certainly something I like the look of. I'm really struck by his assertion that we don't need a...</summary>
    <content type="xhtml" xml:lang="en-US"><div xmlns="http://www.w3.org/1999/xhtml"><p>I'm watching <a href="http://qconlondon.com/london-2010/presentation/When+the+Fur+Flies:+Dev+and+Ops+Cooperation+when+the+Worst+Happens">Michael Nygard's talk</a> in the <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=331">devops track</a> at QCon.  This is my first taste of the devops movement and it's certainly something I like the look of.  I'm really struck by his assertion that we don't need a division between development and operations, but crucially he isn't saying that everyone needs the same skills - we will still have specialists.</p><p>I'm struck that this idea of bringing people together into a single team, while still maintaining specialisation, comes up a lot in the software world.  Some examples:</p><p/><ul>
<li>We always try to have a single User Story implemented by a single team.  There may be different specialist skills required to implement a single feature, but all those skills should be in the same team and the people should work together; we don't want a "back end" team and a "front end" team.</li>
<li>I'm frequently explaining to clients the value of having QA specialists integrated within a development team.</li>
<li>More recently, with <a href="http://www.thekua.com/atwork/">Pat Kua</a>, I've been arguing for the integration of performance testing into the development team.</li>
</ul>
<p/><p>Having a single team has all sorts of implications.  I'm particularly keen on having a single backlog of work, even if not everybody has the skills to pull from that backlog.  Most importantly, a single team stands a better chance of having a single goal than do multiple teams.</p><p>Why are specialist teams so common in software?  My intuition is that it's a social phenomenon that people with similar skills and interests tend to congregate, and like working together.  Finding an effective mechanism to counteract this force, while still maintaining high-skill and specialisation, seems like a Social Technology (in Malcolm Gladwell's terminology) that organisations will need to acquire to be successful.</p></div>
    </content>
    <updated>2010-03-11T10:46:00Z</updated>
    <published>2010-03-10T17:25:16Z</published>
    <author>
      <name>Alistair Jones</name>
    </author>
    <source>
      <id>tag:typepad.com,2003:weblog-1866507</id>
      <link href="http://www.apcjones.com/blog/atom.xml" rel="self" type="application/atom+xml"/>
      <link href="http://hubbub.api.typepad.com/" rel="hub" type="text/html"/>
      <link href="http://www.apcjones.com/blog/" rel="alternate" type="text/html"/>
      <title>Alistair Jones Blog</title>
      <updated>2010-03-15T09:35:27Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-6794675998088145034.post-8770707585421528847</id>
    <link href="http://jupitermoonbeam.blogspot.com/feeds/8770707585421528847/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="https://www.blogger.com/comment.g?blogID=6794675998088145034&amp;postID=8770707585421528847" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/6794675998088145034/posts/default/8770707585421528847" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/6794675998088145034/posts/default/8770707585421528847" rel="self" type="application/atom+xml"/>
    <link href="http://jupitermoonbeam.blogspot.com/2010/03/thoroughly-modern-developer.html" rel="alternate" type="text/html"/>
    <title>A Thoroughly Modern Developer</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">The world of development has changed rapidly over the last decade or so.  Thanks to Agile, great tools such as TDD, O/R mapping, dynamic and functional languages and a million other little things, the way companies approach development is changing.  A bright new future awaits where only the true veterans wince as the CEO discusses going waterfall when promoting the merits of the new hydroelectric generator.<br/><br/>Inevitably, as development changes so will developers need to adapt.  The stereotype of a socially awkward, green screen loving, mouse hating, hacker who wears black-now-grey jeans and t-shirts that state "127.0.0.1 is where the heart is" for a week at a time and mumbles through the pizza crumbs that drop in piles from his beard onto his ever rounding belly, is not going to cut it in this new world.  Future projects will be run on the basis of success and that means you can't forgive someone's shortcomings because they are a "code wizard".<br/><br/>So what sort of developer does cut it at the beginning of this new decade?  What sort of skills are you going to need?  Well, funny you should ask-<br/><h2><br/></h2><h2>Domain Knowledge</h2>Or, knowledge of the business you are working for.  Systems are more complex than ever and businesses increasingly rely on them.  Regardless of the general mistrust of IT it has moved right into the heart of business, providing the engine, one without which many businesses couldn't survive.<br/>To build successful systems The Thoroughly Modern Developer has a thorough knowledge of the businesses intention and the value being delivered; it isn't good enough to rely on a BA and a Development Manager to 'translate' business speak into dev syntax.<br/><br/>Eric Evans goes into this in detail in Domain Driven Design.  Designing and building a system is a collaborative effort between the domain experts and the developers to create a common model (or a ubiquitous language).  If you don't understand the business how can you model it?  But it goes further than that; if you don't understand the business value how can you deliver it?<br/><h2><br/></h2><h2>QA</h2>Back in the old days testing meant running up the app, clicking a couple of times and then waiting a month or two before the testing team raised a list of bugs for the junior devs to pick up and fix.  It took XP to change our attitudes on this.  TDD meant we wrote unit tests and verified our systems with at least some code.  Agile put QAs at the heart of the development process and bugs where fixed at the end of every iteration, but the 'throw it over the wall' principle was still there, just shorter.<br/><br/>The Thoroughly Modern Developer takes responsibility for her own quality, she cares more about meeting the acceptance criteria in a bug free fashion than anything else.  This makes the QA's role even more critical as they must <a href="http://christianralph.blogspot.com/2010/02/menage-trois-in-kinky-teams.html">continuously guide and help the dev</a> but they will no longer be reduced to simply checking they've done the work.<br/><h2><br/></h2><h2>Usability</h2>The average developers idea of building something usable is akin to [the car Homer designed].  For some strange reason even the simplest of tasks, such as getting a column of text boxes to line up, seems to be a feat of incredible endurance.<br/><br/>But usability is crucial.  The first developer I ever worked for told me The users don't care about how clean and beautiful your code is, they never see it, but the smallest spelling mistake on the UI and they're on the phone.<br/><br/>The Thoroughly Modern Developer builds systems with usability in mind from the start.  Sure, she's no expert - but she knows enough simple rules to get her by - so she works closely with the UX person to ensure what is being produced is usable not just functional.<br/><h2><br/></h2><h2>Polyglot</h2>The Thoroughly Modern Developer does not define her role or skillset around a single language (or worse, a single toolkit - i.e. ASP.NET Developer). <br/><br/>She is language agnostic, and she has experience of a number of different languages, using different paradigms (OOP, functional, dynamic etc.) and her level of understanding goes beyond syntax. <br/>The Thoroughly Modern Developer will choose the best tool for the job or circumstance.  Throw her a language she's never worked in and she has no issues about picking it up.  Or put her on a project where she's expected to work in two or more different languages and she isn't phased.<br/><br/>In <a href="http://en.wikipedia.org/wiki/Code_Complete">Code Complete</a> Steve McConnell talks about Programming "into" a langague over programming "in" a language.  The Thoroughly Modern Developer does the former.<br/><h2><br/></h2><h2>Value Driven</h2>To every new feature, ever request, every line of code, the Thoroughly Modern Developer asks the same question: how does this deliver value or what's the value of doing this?  She's obsessed, she keeps going on about it, it's all most as if it's all she cares about.<br/><br/>Which it is of course.  To the Thoroughly Modern Developer value is the sole purpose of her job.<br/><h2><br/></h2><h2>A People Person</h2>Oh yes, it's that horrible phrase, one that causes many devs of old to run away and hide behind a wall of cabinets filled with specification documents.  The Thoroughly Modern Developer, on the other hand, likes people, gets on with people, can talk to people.  She doesn't need 'Relationship Managers' or 'Business Interfacers'; put her in a room full of real people and she'll hold her own without spitting when she talks or snorting Beavis and Buthead style when someone uses any word, or collection of words, which bear a vague resemblance to bodily functions.<br/><br/>Why is the Thoroughly Modern Developer such a people person?  Because she understands that in order to build quality software, that delivers business value she needs to talk to people, all different sorts of people, all the time.  Whether it's to find out whether the button should say Save or Create or to explain to non-technical people why it took longer to integrate the zobertron with the phlargbleg initiator (of course the Thoroughly Modern Developer would never have come up with those names but she's still got to get along with the old skool) and for the client to be confidant.<br/><br/>People are what makes a software project successful and if you can't do people you can't do software.<br/><h2><br/></h2><h2>Facilitation</h2>The Thoroughly Modern Developer often finds herself in the middle of difficult and complex situations.  Because she wants to get the system right she has to raise difficult questions about the way the business works. <br/><br/>The Thoroughly Modern Developer needs basic facilitation skills.  She needs to be able to lead a group of people through creative and difficult exercises. To get the right answers you have to keep people on track, resolve conflicts, remove distractions, know when to call time-out, get them to make a decision. <br/><h2><br/></h2><h2>Has "other" interests</h2>For athletes <a href="http://www.britishrowing.org/indoor/cross-training">cross-training</a> (training in your non-core sport) is a essential technique to ensuring you excel in your core discipline.  This is no less true for intellectual disciplines and even more true for creative ones (artists/writers/musicians have known for centuries the importance of pursing other arts - think Da Vinci).  If your entire existence is writing software then you are greatly narrowing your reference points and are more likely to suffer from boredom or stagnation.  For example many prominent developers have blogged on the strange <a href="http://www.codinghorror.com/blog/2009/01/the-one-thing-programmers-and-musicians-have-in-common.html">relation between developmen</a>t and <a href="http://www.threeriversinstitute.org/blog/?p=435">music</a> (as a failed musician I entirely concur). <br/><br/>Personally, I have found that long distance sports have allowed me to strengthen and develop a lot of essential development skills: focus, pace, general discipline; not to mention the health benefits that keep my brain active and my energy levels high.<br/><br/>But not only does it benefit your work but it makes you a more interesting person, which is always useful when talking to 'real' people like the users. So do your self a favour, when you get home do something that doesn't involve the computer.<br/><h2><br/></h2><h2>Understands that technology isn't important</h2>The Thoroughly Modern Developer has a healthy cynicism towards technology. If something can be done without technology that's her preference and she'll push for it.  She actually wants to <a href="http://gettingreal.37signals.com/ch10_Less_Software.php">write less software</a>; complex clever gadgetry and features fill her with a great sense of foreboding.<br/><br/>If she was a developer at Timpsons (who have no centralized till system), she'd be strong in resisting all efforts to introduce one.  She only cares about technology if it offers real benefit, if it provides genuine value or is essential to the business or user. <br/><br/><br/>She's great is the Thoroughly Modern Developer.  She's so awesome people high five her every time she gets up to make a cup of tea.  And yet she's so humble with it.  If only I could be just like her (sigh).<div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/6794675998088145034-8770707585421528847?l=jupitermoonbeam.blogspot.com" width="1"/></div></div>
    </content>
    <updated>2010-03-11T10:26:04Z</updated>
    <published>2010-03-11T10:24:00Z</published>
    <author>
      <name>Peter Gillard-Moss</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/10275408277486693139</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-6794675998088145034</id>
      <author>
        <name>Peter Gillard-Moss</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/10275408277486693139</uri>
      </author>
      <link href="http://jupitermoonbeam.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.blogger.com/feeds/6794675998088145034/posts/default" rel="self" type="application/atom+xml"/>
      <link href="http://jupitermoonbeam.blogspot.com/" rel="alternate" type="text/html"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://www.blogger.com/feeds/6794675998088145034/posts/default?start-index=26&amp;max-results=25" rel="next" type="application/atom+xml"/>
      <title>Jupiter Moonbeam &amp; the Geeks from Cyberspace</title>
      <updated>2010-03-13T11:21:54Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.markhneedham.com/blog/?p=2246</id>
    <link href="http://feedproxy.google.com/~r/MarkNeedham/~3/_fBJ7-yGNqk/" rel="alternate" type="text/html"/>
    <title>Does an organisation need to be fully committed to agile/lean/scrum?</title>
    <summary>Alan Atlas has a recent blog post where he discusses agile, lean and scrum and suggests that you can't truly achieve agility unless your company is fully committed to it which differs slightly from my experiences.
Alan makes a valid point that we're not really following an approach just because we use all the practices:

Many people [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Alan Atlas has <a href="http://www.rallydev.com/agileblog/2010/03/taking-sides/">a recent blog post where he discusses agile, lean and scrum and suggests that you can't truly achieve agility unless your company is fully committed to it</a> which differs slightly from my experiences.</p>
<p>Alan makes a valid point that we're not really following an approach just because we use all the practices:</p>
<blockquote><p>
Many people make the mistake of viewing Scrum and Agile and Lean as sets of practices. “If I do kanban, I’m Lean.” “If I do sprints, I’m scrummy.”
</p></blockquote>
<p>It's quite easy to put our work up on a story wall, <a href="http://www.scrumalliance.org/articles/140"> run a daily standup</a> and <a href="http://thedailywtf.com/Articles/Unit-Tested.aspx">unit test our code</a> and not really get the full benefit that those practices are supposed to give us.</p>
<p>As I've mentioned before though I think it is <a href="http://www.markhneedham.com/blog/2010/02/26/shu-ha-ri-harmful/">part of the learning process that we start out focusing on practices</a> and not principles.</p>
<p>However, at some stage we need to start thinking for ourselves about the value those are giving and making adjustments to them if we're not seeing much value i.e. we need to look beyond the practice and to the principle or outcome that we are trying to achieve by using that practice.</p>
<p>The part of the post which is different to my experiences is this bit:</p>
<blockquote><p>
So I smile to myself (I think it’s to myself) when I hear management say things like “We’ll never be totally Agile in this company. There will always be waterfall projects.” I smile because what that really means is that they’ll never be Agile at all.
</p></blockquote>
<p>I haven't heard conversations like this before but I think it is still possible to deliver software in a team working in an 'agile' way even if the rest of the organisation which that team operates in follows a different approach.</p>
<p>It won't be as smooth sailing as if the whole organisation buys into the lean/agile approach and there will still be some reporting and bureaucracy that you need to deal with but it's not a lost cause.</p>
<p>My colleague Lindy Stephens and a couple of others covered some of the issues around project governance in the enterprise in a <a href="http://www.markhneedham.com/blog/2009/10/01/qtb-agile-governance-managing-the-enterprise-issues/">ThoughtWorks QTB in Sydney last year</a>. The <a href="http://www.slideshare.net/ThoughtWorks/agile-governance-managing-the-enterprise-issues-2195039">slides from that presentation are available on slideshare</a>.</p>
<blockquote><p>
If your company is not fully committed to agility then you won’t achieve it, and your results will be a self-fulfilling prophecy of unrealized potential.
</p></blockquote>
<p>Even if an organisation decides that it wants to be agile I think it still takes time to get used to the approach and it always seems to take a few successful deliveries to see that some of the worries that heavy weight processes and paperwork try to protect you against are not necessarily valid.</p>
<p>I've spent a lot of time being indignant that people didn't buy into the agile approach but the more I spend time in different organisations the more it becomes clear that even for the people with the best intentions in wanting to learn this approach it will still take time to get there.</p>
<p>I'm coming to the conclusion that it's a good thing that people have some level of skepticism because it forces you to really understand why an agile approach is more effective and then try and persuade other people of that. </p>
<p>It's also helpful to note that it makes sense to vary our approach depending on the context that we're operating in. For example if the team is distributed across different cities then we might have more written documentation than with a co-located team. </p>
<p>It's very rare that an organisation or group of people will just 'get it' straight away – in many ways it's quite an iterative/incremental journey.</p>
<img height="1" src="http://feeds.feedburner.com/~r/MarkNeedham/~4/_fBJ7-yGNqk" width="1"/></div>
    </content>
    <updated>2010-03-11T08:05:28Z</updated>
    <category term="Software Development"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.markhneedham.com/blog/2010/03/11/does-an-organisation-need-to-be-fully-committed-to-agileleanscrum/</feedburner:origlink>
    <author>
      <name>Mark Needham</name>
    </author>
    <source>
      <id>http://www.markhneedham.com/blog</id>
      <link href="http://www.markhneedham.com/blog" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/MarkNeedham" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Thoughts on Software Development</subtitle>
      <title>Mark Needham</title>
      <updated>2010-03-15T01:04:09Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://del.icio.us/brunns#2010-03-10</id>
    <link href="http://feedproxy.google.com/~r/SmallValuesOfCool/~3/S52vEunrneo/brunns" rel="alternate" type="text/html"/>
    <title>Links for 2010-03-10 [del.icio.us]</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><ul>
<li><a href="http://everythinglinux.org/rsync/">Rsync Tutorial</a></li>
<li><a href="http://www.guardian.co.uk/commentisfree/2010/mar/10/facebook-groups-internet-hadley-freeman">Facebook groups are the new lynch mobs</a></li>
<li><a href="http://www.youtube.com/watch?v=7H0K1k54t6A">YouTube - Future Designer laptop</a><br/>
Cool.</li>
<li><a href="http://groups.google.com/group/comp.lang.python/msg/b977ed1312e10b21">Principle of least privilege, or Private by convention?</a></li>
<li><a href="http://www.bbc.co.uk/iplayer/console/6music/">BBC 6 Music - Listen live</a></li>
<li><a href="http://grognardia.blogspot.com/2010/03/retrospective-skyrealms-of-jorune.html">Retrospective: Skyrealms of Jorune</a><br/>
I bought but never played this.</li>
<li><a href="http://www.antipope.org/charlie/blog-static/2010/03/for-sale-first-edition-of-the.html">For sale; first edition of the Necronomicon (used once)</a><br/>
Roleplaying game based on Charles Stross's Laundry Files novels. They are a good read, but I prefer the very similar but somewhat darker Delta Green milieu.</li>
</ul></div>
    </summary>
    <updated>2010-03-11T08:00:00Z</updated><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://del.icio.us/brunns#2010-03-10</feedburner:origlink>
    <source>
      <id>http://www.brunningonline.net/simon/blog/</id>
      <author>
        <name>Simon Brunning</name>
        <email>simon.brunning+smallvaluescomment@gmail.com</email>
      </author>
      <link href="http://www.brunningonline.net/simon/blog/" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/SmallValuesOfCool" rel="self" type="application/rss+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <rights>Copyright 2010</rights>
      <subtitle>Simon Brunning - stuff that I find interesting</subtitle>
      <title>Small Values of Cool</title>
      <updated>2008-10-08T13:18:28Z</updated>
    </source>
  </entry>

  <entry>
    <id>http://betarelease.github.com/2010/03/11/want-to-be-a-trainer</id>
    <link href="http://betarelease.github.com/2010/03/11/want-to-be-a-trainer.html" rel="alternate" type="text/html"/>
    <title>Why should you be a trainer?</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><h1>Why should you be a trainer?</h1>
<p>After being thoroughly impressed by the <a href="http://betarelease.github.com/atom.xml">training</a> that I received when I joined ThoughtWorks I was driven to become a trainer myself. I did that in 2008 (yes it’s already been that long) and am a different person professionally since then.</p>
<p>I am documenting my experiences for future reference as a mulitpost on Training. As I continue posting the topics on the list here will become active. Maybe as you read it will excite you to be a trainer too.</p>
<ol>
	<li>Preparation
	<ol>
		<li><a href="http://betarelease.github.com/2010/01/02/prepare-to-be-a-trainer.html">Preparing to be a trainer</a></li>
		<li>Preparing the Venue</li>
	</ol></li>
	<li>Training to be a Trainer
	<ol>
		<li>Science of Learning</li>
		<li>Cognition</li>
		<li>Psychology of a trainee/student/learner</li>
		<li>Training tools</li>
		<li>Imaginative use of training tools to suit trainee/trainer/class</li>
		<li>Studying the material</li>
		<li>Suiting the training material to your style and needs</li>
		<li>Dry runs</li>
	</ol></li>
	<li>Delivering as a Trainer
	<ol>
		<li>Preparing for the session
		<ol>
			<li>Seating</li>
			<li>Be ready with the accessories for the session</li>
			<li>Prepare the material</li>
		</ol></li>
		<li>How to present yourself and still be yourself</li>
		<li>Finishing up the day</li>
		<li>Coaching/Mentoring/One-on-one training</li>
	</ol></li>
	<li>Feedback – Desiging training
	<ol>
		<li>Updating session content</li>
		<li>Updating training style</li>
		<li>Updating training schedule</li>
		<li>Updating training theme</li>
		<li>Adding new content</li>
		<li>Applying what you learnt as a trainer to your profession</li>
	</ol></li>
</ol></div>
    </content>
    <updated>2010-03-11T08:00:00Z</updated>
    <source>
      <id>http://betarelease.github.com/</id>
      <author>
        <name>Sudhindra Rao</name>
        <email>srrao2k (at) gmail.com</email>
      </author>
      <link href="http://betarelease.github.com/atom.xml" rel="self" type="application/atom+xml"/>
      <link href="http://betarelease.github.com/" rel="alternate" type="text/html"/>
      <title>Sudhindra Rao</title>
      <updated>2010-03-12T19:54:00Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://bill.lachfarm.com/?p=41</id>
    <link href="http://bill.lachfarm.com/?p=41" rel="alternate" type="text/html"/>
    <title>Build &amp; Deploy</title>
    <summary>I’ve been working for the last 5 months on build &amp; deploy type projects. Both have been using Maven. I had started off convinced that it was pure evil. Many colleagues claim there is no place for it. I don’t know if I am convinced. Being with a central build and deploy team, responsible for [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I’ve been working for the last 5 months on build &amp; deploy type projects. Both have been using Maven. I had started off convinced that it was pure evil. Many colleagues claim there is no place for it. I don’t know if I am convinced. Being with a central build and deploy team, responsible for making sure that up to 20 separate projects can be built and deployed to multiple environments, at differing schedules, Maven has made part of this pretty simple. Many arguments I hear seem very single project focused. They also seem very focused on only open-source dependencies. They also argue that they can manage their dependencies better by themselves, but theres the rub, “<strong>Themselves</strong>“.  With 20 projects possibly managing themselves, and each having to share some environments, and all having to exist together as a product, that would be chaos. As my current client has observed.</p>
<p>Maven has been working (albeit with some pain). I do agree that a better way needs to be figured out and implemented, but I am not loosing any sleep about it.</p></div>
    </content>
    <updated>2010-03-11T03:34:56Z</updated>
    <category term="Build"/>
    <category term="IT"/>
    <author>
      <name>Bill</name>
    </author>
    <source>
      <id>http://bill.lachfarm.com</id>
      <link href="http://bill.lachfarm.com/?feed=rss2" rel="self" type="application/atom+xml"/>
      <link href="http://bill.lachfarm.com" rel="alternate" type="text/html"/>
      <subtitle>some stuff to blatt... about</subtitle>
      <title>Words From an Old Goat - Bill Hegarty</title>
      <updated>2010-03-16T05:03:05Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-6354510176298460211.post-3931399983286832420</id>
    <link href="http://marjoriepries.blogspot.com/feeds/3931399983286832420/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="http://marjoriepries.blogspot.com/2010/03/my-bangalore-adventure-part-20-confined.html#comment-form" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/6354510176298460211/posts/default/3931399983286832420" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/6354510176298460211/posts/default/3931399983286832420" rel="self" type="application/atom+xml"/>
    <link href="http://marjoriepries.blogspot.com/2010/03/my-bangalore-adventure-part-20-confined.html" rel="alternate" type="text/html"/>
    <title>My Bangalore Adventure, part 20: Confined to the Neighborhood</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">My Bangalore explorations ran into a wall after that weekend in Bannerghatta. the The preliminary outings and introductory classes of ThoughtWorks University (TWU) were over and the students and trainers alike were digging into the hard stuff. <br/><br/>My week days generally ran like this: <br/><br/>7:30-8:00: get to the Royal Orchid (a very nice hotel behind the Diamond District) around 7:30 for breakfast, class setup and the trainers’s morning huddle. <br/>9:00: start class.<br/>4:00-5:00: End class.<br/>5:30-6:00: Get to TW offices in time for after-class student presentations or student one-on-one coaching, or grading homework, or trainer meetings or preparing for the next day’s classes. <br/>9:00 approx.: Eat dinner.<br/>10:00-11:00: finish dinner and go back to work. Or sleep. Or maybe blog.<br/><br/>Even Saturdays and Sundays would have TWU things going on. <br/><a href="http://2.bp.blogspot.com/_5QckReMFo3U/S5cPrSvLbvI/AAAAAAAAAFQ/uetImK-AYg8/s1600-h/india+hours.JPG"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5446839510766415602" src="http://2.bp.blogspot.com/_5QckReMFo3U/S5cPrSvLbvI/AAAAAAAAAFQ/uetImK-AYg8/s400/india+hours.JPG" style="float: right; margin: 10 10 10px 10px; cursor: pointer; cursor: hand; width: 400px; height: 250px;"/></a><br/><br/>I’ve included a little chart of my hours before, during, and after TWU to illustrate. That big dip is a a week of vacation and traveling home before starting my next assignment in Chicago.<br/><br/>Given such a schedule, there was little opportunity for getting out beyond the neighborhood. The only birding was along the drainage canal on the way to the Royal Orchid and I was seeing the same birds over and over. If I needed a little more greenery, there was a pretty good public garden down the road across from New Santhi Sagar. A big sign made me think the park’s name was Puravankara but after seeing that name in several places in Bangalore I figured out it was just the name of a real estate developer. The formal name of that park is Domlur SAARC Park. <br/><br/><a href="http://www.flickr.com/photos/11275703@N05/3772114910/" title="P1010008 by mpries, on Flickr"><img alt="Puravankara Park Domlur by M Pries" height="375" src="http://farm4.static.flickr.com/3482/3772114910_1116464743.jpg" width="500"/></a> <br/><br/>SAARC stands for <a href="http://www.saarc-sec.org/main.php" target="blank">South Asian Association for Regional Cooperation</a>, a body that promotes socio-economic development. The second summit of the SAARC was held in 1986 in Bangalore and was the incentive for building out the <a href="http://wikimapia.org/104338/KGA-Karnataka-Golf-Association" target="blank">golf course</a> that is adjacent to the Diamond District and the Royal Orchid.<br/><br/>You can probably figure out what I'm thinking; Puravankara probably developed and donated that little park down the road as public space in conjunction with various deals going on to showcase the area for the benefit of the golfing elite and visiting dignitaries. <br/><br/>Besides that park, taking a walk now meant “going to get the basics” like shopping for groceries on 100 Foot Road or at Total Mall (where we had gone for McDonald’s). Or hunting down a book at <a href="http://www.google.com/search?q=axis+books+%2B+bangalore&amp;rls=com.microsoft:en-us&amp;ie=UTF-8&amp;oe=UTF-8&amp;startIndex=&amp;startPage=1&amp;rlz=" target="blnk">Axis Books</a> on the Inner Ring Road in Domlur. None of these destinations were much more than a mile from my apartment, so “taking a walk” also just meant doing the “same-old, same-old”.<br/><br/>One Sunday I decided to get out and really do something different. We had gone to some very nice restaurants on 80 Foot Road that Rixt, another trainer, knew about. We always went there at night in rickshaws but it seemed fairly close, just a few turns down twisty streets and <em>voila!</em> ... dining and shopping sophistication appeared. I had a small paper map from a hotel tourist magazine and it looked like I could walk there in about 20 minutes.<br/><br/>That little map suggested that 80 Foot Road branched directly off a street that joined Airport Road beside the Leela Palace Hotel. <em>Easy! Let's do it!</em><br/><br/>My walk started with an ordinary stroll along Airport Road, across the pedestrian bridge, and past the front gate of Leela Palace. I turned the corner onto Kodihalli Main Road, a broad shady street that borders the hotel. This section has some impressive homes across from the hotel and although narrower, reminded me of spots along 100 Foot Road. But after a few blocks, the street shrank and I fell victim to the mapmaker’s imagination, or was that misinformation?<br/><br/><a href="http://www.flickr.com/photos/11275703@N05/3731913367/" title="P1010093 by mpries, on Flickr"><img height="500" src="http://farm3.static.flickr.com/2467/3731913367_966867ce7e.jpg" width="375"/></a><br/><br/>A pretty white mosque with green trim lay ahead near a fork in the road. According to my little map, the right-hand branch was the connection to 80 Ft. Road but to my eyes, it just looked like a crooked dirt alley running between houses. There were no obvious street signs to help me out. So I stayed to my left, on the side of the fork that went past the mosque. As I passed, it blasted my ears with a loud broadcast call to prayer. <br/><br/>It was like a foghorn marking a ship’s passage into unknown waters. I had been sure I was headed for the trendy part of 80 Foot Road but soon it would seem I was on course, quickly, for some other place.... (<em>to be continued</em>)<div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/6354510176298460211-3931399983286832420?l=marjoriepries.blogspot.com" width="1"/></div></div>
    </content>
    <updated>2010-03-11T03:02:00Z</updated>
    <published>2010-03-11T03:02:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="Diamond District"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="TWU"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="ThoughtWorks India"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Domlur"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Axis Books"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="ThoughtWorks University"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="SAARC"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Kodihalli"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Bangalore"/>
    <author>
      <name>Marjorie Pries</name>
      <email>noreply@blogger.com</email>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-6354510176298460211</id>
      <author>
        <name>Marjorie Pries</name>
        <email>noreply@blogger.com</email>
      </author>
      <link href="http://marjoriepries.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.blogger.com/feeds/6354510176298460211/posts/default" rel="self" type="application/atom+xml"/>
      <link href="http://marjoriepries.blogspot.com/" rel="alternate" type="text/html"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://www.blogger.com/feeds/6354510176298460211/posts/default?start-index=26&amp;max-results=25" rel="next" type="application/atom+xml"/>
      <title>Marjorie Pries: Don't believe everything you think</title>
      <updated>2010-03-12T21:44:17Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.markhneedham.com/blog/?p=2241</id>
    <link href="http://feedproxy.google.com/~r/MarkNeedham/~3/FFw3Zph0XhE/" rel="alternate" type="text/html"/>
    <title>Javascript: Function scoping</title>
    <summary>My colleague John Hume wrote an interesting post about his experience with the 'const' keyword in ActionScript where he describes the problems with trying to capture a loop variable in a closure and then evaluating it later on in the code.
Since ActionScript and JavaScript are both dialects of ECMAscript, this is a problem in JavaScript [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>My colleague John Hume wrote <a href="http://elhumidor.blogspot.com/2010/03/actionscript-const-gotcha.html">an interesting post about his experience with the 'const' keyword in ActionScript</a> where he describes the problems with trying to capture a loop variable in a closure and then evaluating it later on in the code.</p>
<p>Since ActionScript and JavaScript are both dialects of <a href="http://en.wikipedia.org/wiki/ECMAScript">ECMAscript</a>, this is a problem in JavaScript as well, and is due to the fact that variables in JavaScript have <a href="http://www.slideshare.net/douglascrockford/crockford-on-javascript-act-iii-function-the-ultimate">function scope rather than block scope</a> which is the case in many other languages.</p>
<p>This problem would tend to reveal itself in code where we try to capture a loop variable in an anonymous function and use it later on, like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> getValues<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
       x<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #000066; font-weight: bold;">return</span> i<span style="color: #339933;">;</span> <span style="color: #009900;">}</span>
    <span style="color: #009900;">}</span>
    <span style="color: #000066; font-weight: bold;">return</span> x<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span><span style="color: #339933;">;</span>
 
<span style="color: #003366; font-weight: bold;">var</span> values <span style="color: #339933;">=</span> getValues<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;</span> values.<span style="color: #006600;">length</span><span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    console.<span style="color: #006600;">log</span><span style="color: #009900;">(</span>values<span style="color: #009900;">[</span>j<span style="color: #009900;">]</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span></pre></div></div>

<p>We might expect that to print the sequence of numbers 0-9 on the screen but what we actually get is '10′ printed 10 times.</p>
<p>There are a couple of things that I initially found strange about this:</p>
<ol>
<li>Why doesn't it print out the numbers 0-9?</li>
<li>Given that it doesn't do that why does it print out '10′ 10 times instead of '9′ 10 times?</li>
</ol>
<p>The answer to the first question is that 'i' gets assigned a new value on each iteration of the loop and we don't evaluate 'i' until we evaluate the anonymous function on line 11.</p>
<p>The value when we do evaluate it would be the last value that it was set to by the loop which in this case that would be '10′ because that's the value that 'i' has to be <a href="http://twitter.com/jason_diamond/statuses/10283944438">in order for</a> <a href="http://twitter.com/drunkcod/statuses/10283979588">the loop to terminate</a>.</p>
<p>This is <a href="http://twitter.com/davcamer/statuses/10290979811">actually a problem in C# as well</a> – the following code will output '10′ 10 times as well:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp"><span style="color: #000000;">[</span>Test<span style="color: #000000;">]</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ClosureOnTheSameValue<span style="color: #000000;">(</span><span style="color: #000000;">)</span>
<span style="color: #000000;">{</span>
    var values <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span>Func<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;&gt;</span><span style="color: #000000;">(</span><span style="color: #000000;">)</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF;">for</span><span style="color: #000000;">(</span><span style="color: #FF0000;">int</span> i<span style="color: #008000;">=</span><span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">10</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #000000;">)</span>
    <span style="color: #000000;">{</span>
        values.<span style="color: #0000FF;">Add</span><span style="color: #000000;">(</span><span style="color: #000000;">(</span><span style="color: #000000;">)</span> <span style="color: #008000;">=&gt;</span> i<span style="color: #000000;">)</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">}</span>
 
    <span style="color: #0600FF;">foreach</span> <span style="color: #000000;">(</span>var value <span style="color: #0600FF;">in</span> values<span style="color: #000000;">)</span>
    <span style="color: #000000;">{</span>
        Console.<span style="color: #0000FF;">WriteLine</span><span style="color: #000000;">(</span>value<span style="color: #000000;">(</span><span style="color: #000000;">)</span><span style="color: #000000;">)</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">}</span>
<span style="color: #000000;">}</span></pre></div></div>

<p>Again we capture 'i' inside a closure and since we only evaluate that value when it's actually used it will always refer to the last value that 'i' was set to which in this case means that it will always output a value of 10.</p>
<p>To fix this in C# we could just create a temporary variable – something which Resharper will actually suggest to us:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp"><span style="color: #000000;">[</span>Test<span style="color: #000000;">]</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ClosureOnDifferentValue<span style="color: #000000;">(</span><span style="color: #000000;">)</span>
<span style="color: #000000;">{</span>
    var values <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span>Func<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;&gt;</span><span style="color: #000000;">(</span><span style="color: #000000;">)</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF;">for</span><span style="color: #000000;">(</span><span style="color: #FF0000;">int</span> i<span style="color: #008000;">=</span><span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">10</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #000000;">)</span>
    <span style="color: #000000;">{</span>
        var idash <span style="color: #008000;">=</span> i<span style="color: #008000;">;</span>
        values.<span style="color: #0000FF;">Add</span><span style="color: #000000;">(</span><span style="color: #000000;">(</span><span style="color: #000000;">)</span> <span style="color: #008000;">=&gt;</span> idash<span style="color: #000000;">)</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">}</span>
 
    <span style="color: #0600FF;">foreach</span> <span style="color: #000000;">(</span>var value <span style="color: #0600FF;">in</span> values<span style="color: #000000;">)</span>
    <span style="color: #000000;">{</span>
        Console.<span style="color: #0000FF;">WriteLine</span><span style="color: #000000;">(</span>value<span style="color: #000000;">(</span><span style="color: #000000;">)</span><span style="color: #000000;">)</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">}</span>
<span style="color: #000000;">}</span></pre></div></div>

<p>This works in C# because variables have block scope which means that we have a new version of 'idash' for each of the functions that we add to the 'values' collection.</p>
<p>Sadly the same trick doesn't work in JavaScript because variables have function scope in Javascript:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> getValues<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
       <span style="color: #003366; font-weight: bold;">var</span> idash <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
       x<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #000066; font-weight: bold;">return</span> idash<span style="color: #339933;">;</span> <span style="color: #009900;">}</span>
    <span style="color: #009900;">}</span>
    <span style="color: #000066; font-weight: bold;">return</span> x<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span><span style="color: #339933;">;</span>
 
<span style="color: #003366; font-weight: bold;">var</span> values <span style="color: #339933;">=</span> getValues<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;</span> values.<span style="color: #006600;">length</span><span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    console.<span style="color: #006600;">log</span><span style="color: #009900;">(</span>values<span style="color: #009900;">[</span>j<span style="color: #009900;">]</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span></pre></div></div>

<p>The 'idash' temporary variable that we created to try and solve the problem gets assigned a new value in each iteration of the loop because that variable is only declared once for the whole function. </p>
<p>The code above could be written like this to make that clearer:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> getValues<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> idash<span style="color: #339933;">;</span>
 
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
       idash <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
       x<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #000066; font-weight: bold;">return</span> idash<span style="color: #339933;">;</span> <span style="color: #009900;">}</span>
    <span style="color: #009900;">}</span>
    <span style="color: #000066; font-weight: bold;">return</span> x<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span><span style="color: #339933;">;</span>
 
<span style="color: #003366; font-weight: bold;">var</span> values <span style="color: #339933;">=</span> getValues<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;</span> values.<span style="color: #006600;">length</span><span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    console.<span style="color: #006600;">log</span><span style="color: #009900;">(</span>values<span style="color: #009900;">[</span>j<span style="color: #009900;">]</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span></pre></div></div>

<p>As John points out:</p>
<blockquote><p>
Here's something I either never knew or at some point forgot about JavaScript: variables are lexically scoped, but only function bodies introduce new lexical scopes.
</p></blockquote>
<p>In this case we actually end up printing '9′ 10 times because that's the maximum value that gets assigned to 'idash'.</p>
<p>One solution is to create a temporary variable inside an anonymous function that we execute immediately, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> getValues<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
        <span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
            <span style="color: #003366; font-weight: bold;">var</span> idash <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
            x<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #000066; font-weight: bold;">return</span> idash<span style="color: #339933;">;</span> <span style="color: #009900;">}</span> <span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">}</span>
    <span style="color: #000066; font-weight: bold;">return</span> x<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span><span style="color: #339933;">;</span>
 
<span style="color: #003366; font-weight: bold;">var</span> values <span style="color: #339933;">=</span> getValues<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;</span> values.<span style="color: #006600;">length</span><span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    console.<span style="color: #006600;">log</span><span style="color: #009900;">(</span>values<span style="color: #009900;">[</span>j<span style="color: #009900;">]</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span></pre></div></div>

<p>Now 'idash' is scoped inside the anonymous function and we therefore end up with a new value each time like we want.</p>
<p><a href="http://twitter.com/raphscallion/statuses/10288673700">Raph</a> pointed out that we could achieve the same thing in a simpler way with the following code:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> getValues<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    <span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">)</span> <span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span>i<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
        x<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #000066; font-weight: bold;">return</span> i<span style="color: #339933;">;</span> <span style="color: #009900;">}</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #009900;">(</span>i<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> x<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span><span style="color: #339933;">;</span>
 
<span style="color: #003366; font-weight: bold;">var</span> values <span style="color: #339933;">=</span> getValues<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;</span> values.<span style="color: #006600;">length</span><span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
    console.<span style="color: #006600;">log</span><span style="color: #009900;">(</span>values<span style="color: #009900;">[</span>j<span style="color: #009900;">]</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span></pre></div></div>

<p>Here we define a for loop with just a single statement so we can lose the '{}' and just call an anonymous function passing in 'i'.</p>
<p>Of course this example is truly contrived but I wanted to pick something simple enough that I could try and follow exactly how it worked.</p>
<p>I'm not entirely sure of the terminology around closures and scoping so if I've described anything incorrectly then please correct me!</p>
<img height="1" src="http://feeds.feedburner.com/~r/MarkNeedham/~4/FFw3Zph0XhE" width="1"/></div>
    </content>
    <updated>2010-03-10T23:06:31Z</updated>
    <category term="Javascript"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.markhneedham.com/blog/2010/03/10/javascript-function-scoping/</feedburner:origlink>
    <author>
      <name>Mark Needham</name>
    </author>
    <source>
      <id>http://www.markhneedham.com/blog</id>
      <link href="http://www.markhneedham.com/blog" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/MarkNeedham" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Thoughts on Software Development</subtitle>
      <title>Mark Needham</title>
      <updated>2010-03-15T01:04:10Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://watchitlater.com/blog/?p=182</id>
    <link href="http://watchitlater.com/blog/2010/03/post-redirect-get-in-rails/" rel="alternate" type="text/html"/>
    <title>Post-Redirect-Get in Rails</title>
    <summary>For a while now I’ve been flying the flag for using a post-redirect-get design pattern when writing web applications. In my opinion the current crop of web frameworks still make it very easy to do the “bad” thing since to do PRG properly you need to think what kind of an interaction you want with [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>For a while now I’ve been flying the flag for using a <a href="http://en.wikipedia.org/wiki/Post/Redirect/Get">post-redirect-get</a> design pattern when writing web applications. In my opinion the current crop of web frameworks still make it very easy to do the “bad” thing since to do PRG properly you need to think what kind of an interaction you want with users and not cop out saying its technically very difficult in &lt;insert framework here&gt;. If you resort to ActiveX controls, popups without navigation bars and/or weird javascript hacks to stop users from clicking refresh or back buttons then perhaps you should have written a better web application.</p>
<p>Whenever I play with Rails, or for that matter any other web framework, I get stuck on trying to find a problem to solve (or a set of requirements). Fortunately the <a href="http://pragprog.com/titles/rails3/agile-web-development-with-rails-third-edition">Agile Development with Rails</a> book from the Pragmatic Programmers has a nice little bookstore application that I can develop iteratively. I’ve put my latest adaptation of their depot application to use post-redirect-get (even works with ActiveResource scaffolds), UUIDs as ActiveRecord primary keys, HAML, SASS and RSpec on <a href="http://github.com/tomcz/pragprog-depot-prg">GitHub</a>. Feedback is always welcome.</p></div>
    </content>
    <updated>2010-03-10T13:06:28Z</updated>
    <category term="My Code"/>
    <category term="Software Development"/>
    <category term="github"/>
    <category term="haml"/>
    <category term="post-redirect-get"/>
    <category term="rails"/>
    <category term="resource"/>
    <category term="REST"/>
    <category term="rspec"/>
    <category term="ruby"/>
    <category term="sass"/>
    <author>
      <name>Tom</name>
    </author>
    <source>
      <id>http://watchitlater.com/blog</id>
      <link href="http://watchitlater.com/blog/feed/" rel="self" type="application/atom+xml"/>
      <link href="http://watchitlater.com/blog" rel="alternate" type="text/html"/>
      <subtitle>A reluctant foray into the world of blogging.</subtitle>
      <title>No One Is Perfect</title>
      <updated>2010-03-15T02:03:49Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://blog.gigoo.org/?p=4903</id>
    <link href="http://blog.gigoo.org/2010/03/10/what-is-your-favorite-development-platform-survey-results/" rel="alternate" type="text/html"/>
    <title>What is your favorite development platform, survey results</title>
    <summary>Not to long ago I posted an article on my favorite environment for software development. There was also a survey in that post asking about your favorite environment. The results are below.

Clearly, Linux is a winner. Here are some comments you guys added to a survey.

Can’t believe people are still using text editors to code… [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Not to long ago I posted an article on my favorite environment for software development. There was also a survey in that post asking about your favorite environment. The results are below.</p>
<p style="text-align: center;"><img alt="" class="aligncenter" src="http://chart.apis.google.com/chart?cht=p3&amp;chco=0000FF&amp;chd=t:62.5,9.4,28.1&amp;chl=Linux|Windows|Mac%20OS%20X&amp;chs=500x250"/></p>
<p style="text-align: left;">Clearly, Linux is a winner. Here are some comments you guys added to a survey.</p>
<blockquote>
<p style="text-align: left;">Can’t believe people are still using text editors to code… Visual studio rocks!</p>
</blockquote>
<p>Well, not sure about this comment <img alt=":)" class="wp-smiley" src="http://blog.gigoo.org/wp-includes/images/smilies/icon_smile.gif"/> </p>
<blockquote>
<p style="text-align: left;">Well, Ubuntu. For the package system, for the standard package archives and for the PPAs. And for everything else about it being good enough.</p>
</blockquote>
<blockquote>
<p style="text-align: left;">Windows 7, mainly because ive been using windows for, well ever. I find it really intuitive and i just know the tools really well. Windows 7 is really nice too.</p>
</blockquote>
<blockquote>
<p style="text-align: left;">Obviously I long for the day that will never come when I can develop my .net applications in intellij, deploy to a cut down windows vm for compilation and testing against iis… Anyway dreaming aside I pick mac osx for reasons you said and also because I have one and nothing beats dev on a native machine…</p>
</blockquote>
<blockquote>
<p style="text-align: left;">Mac is quite reasonable. Windows just feels clunky.</p>
</blockquote>
<blockquote>
<p style="text-align: left;">I need to be able to navigate to files and find things quickly, let alone use apps. Windows explorer/cmd is crap. Linux and Mac OS both work quickly and the command-line is effective. Mac OS X, however, just requires less of my time to maintain it than Linux. All three work similar from within an app like Eclipse.</p>
</blockquote>
<blockquote>
<p style="text-align: left;">Could be interpreted as a fan oy phrase, but for dev there is no better option than Linux…</p>
</blockquote>
<blockquote>
<p style="text-align: left;">I prefer Max because when I develop I am not just programming. Sometimes I need to check some screencast and last time that I used Linux (last year) I was not able to check all of them. Also I need a good mail and contact manager, I tried Thunderbird and Evolution. But none of them where satisfying my need.<br/>
Also i use my computer to develop and for personal use (creating video, music viewing videos). Linux is poor on that side.</p>
</blockquote>
<blockquote>
<p style="text-align: left;">I still have to fall back to Windows when working with clients who insist on using Outlook for calendaring and those horrible built-in surveys. Some aspects of my MacBook are pleasant, but I detest the keyboard layout – no home/end/pgup/pgdown and, worst of all, no visible # key <img alt=":(" class="wp-smiley" src="http://blog.gigoo.org/wp-includes/images/smilies/icon_sad.gif"/> </p>
</blockquote>
<p style="text-align: left;">We all got a favorite environment, but what is the actual one that you use every day at work? I’m using Visual Studio as there is no real aternative to .NET development. Fortunatelly ReSharper makes it usable <img alt=":)" class="wp-smiley" src="http://blog.gigoo.org/wp-includes/images/smilies/icon_smile.gif"/> </p>
<p style="text-align: left;">Thanks for your answers guys, Greg</p></div>
    </content>
    <updated>2010-03-10T13:03:14Z</updated>
    <category term="development"/>
    <category term="stuff"/>
    <category term="environment"/>
    <category term="linux"/>
    <category term="mac"/>
    <category term="windows"/>
    <author>
      <name>Greg Gigon</name>
    </author>
    <source>
      <id>http://blog.gigoo.org</id>
      <link href="http://blog.gigoo.org/category/development/feed/" rel="self" type="application/atom+xml"/>
      <link href="http://blog.gigoo.org" rel="alternate" type="text/html"/>
      <subtitle>wEBbLOG</subtitle>
      <title>Gigu's blog » development</title>
      <updated>2010-03-10T14:03:20Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://fragmental.tw/?p=162</id>
    <link href="http://feedproxy.google.com/~r/fragmental/tw/~3/mb8AjfN-uLA/" rel="alternate" type="text/html"/>
    <link href="http://fragmental.tw/2010/03/10/everyday-tales-anatomy-of-a-refactoring-%e2%80%93-part-3/#comments" rel="replies" type="text/html"/>
    <link href="http://fragmental.tw/2010/03/10/everyday-tales-anatomy-of-a-refactoring-%e2%80%93-part-3/feed/atom/" rel="replies" type="appication/atom+xml"/>
    <title xml:lang="en">Everyday Tales: Anatomy of a Refactoring – Part 3</title>
    <summary xml:lang="en">We finished last post with this funny situation: the abstraction that represents Facebook depends on our Domain Model.

It was a bit obvious that what we needed was not only system abstractions for Facebook, Twitter and the like but Bounded Contexts. We need to acknowledge the fact that these domains are not part of our model, [...]</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p><a href="http://fragmental.tw/2010/03/10/everyday-tales-anatomy-of-a-refactoring-&#x2013;-part-2/">We finished last post</a> with this funny situation: the abstraction that represents Facebook depends on our Domain Model.</p>
<p><img alt="" src="http://farm5.static.flickr.com/4050/4421591279_88320f11a6_o.jpg"/></p>
<p>It was a bit obvious that what we needed was not only system abstractions for Facebook, Twitter and the like but Bounded Contexts. We need to acknowledge the fact that these domains are not part of our model, even though we depend on them. We need to make this explicit. </p>
<p>The Facebook API doesn’t have the same concept of User as we do, and neither does Twitter. Someone has to translate from Profiles to Users. We identified the UserRepository as the best candidate for that.</p>
<p>The hugest advantage of this is proper dependency management. If  you remember our last post, we had a circular dependency between system abstractions and our model. It was something like this:</p>
<p> <a href="http://www.flickr.com/photos/pcalcado/4384796832/" title="007.jpg by pcalcado, on Flickr"><img alt="007.jpg" height="180" src="http://farm3.static.flickr.com/2713/4384796832_6dbdcae5a3.jpg" width="500"/></a></p>
<p>But, by isolating message parsing from the user creation, we remove that red line. Facebook doesn’t create Users anymore, therefore it doesn’t depend on AllSocialNetworks/UserRepository. Will fall in a situation closer to this:</p>
<p> <a href="http://www.flickr.com/photos/pcalcado/4421591561/" title="9.jpg by pcalcado, on Flickr"><img alt="9.jpg" height="181" src="http://farm3.static.flickr.com/2793/4421591561_160e06c2d0.jpg" width="500"/></a></p>
<p>Now UserRepository will have access to everything it needs to create valid instances of User –and all it needs are objects returned by the system abstractions. <strong>The circular dependency problem is solved.</strong></p>
<p>While moving this translation away from the system abstractions we learned that our situation was much worse than we first thought. The challenge looked simple, transform this:</p>
<p><img alt="" src="http://farm5.static.flickr.com/4022/4421591403_078fd01c82_o.jpg"/></p>
<p>Into this:</p>
<p><a href="http://www.flickr.com/photos/pcalcado/4422357890/" title="8.jpg by pcalcado, on Flickr"><img alt="8.jpg" height="228" src="http://farm3.static.flickr.com/2708/4422357890_69b7402f3f.jpg" width="500"/></a></p>
<p>But indirect coupling among those classes was so strong that even with multiple levels of tests the effort to migrate all system abstractions to this structure is still in progress.</p>
<p>The Repository class is currently in a weird situation. It was already a very good candidate to be renamed to something else or, even better, split in two or more. After all those changes, though, that class is just too far away from whatever a Repository should be. This will probably be the next major refactoring that we have to do in this system. </p>
<p>But that’s another story, that maybe will be told another day…</p>
<h3>Conclusion</h3>
<p>In this example we went from this:</p>
<p><img alt="" src="http://farm5.static.flickr.com/4027/4384034499_24b667dbb8_o.jpg"/></p>
<p>To this:</p>
<p><a href="http://www.flickr.com/photos/pcalcado/4421591561/" title="9.jpg by pcalcado, on Flickr"><img alt="9.jpg" height="181" src="http://farm3.static.flickr.com/2793/4421591561_160e06c2d0.jpg" width="500"/></a></p>
<p>We sent from seven to thirteen classes. From two to four major packages/modules. Did this really help or we just went nuts on abstraction explosion?</p>
<p>All metrics I have gathered up to this point are positive. I am not talking about abstract metrics like cyclomatic complexity, efferent coupling and etc. –those are useful but won’t tell much without context. What tells me if those changes helped or not is how they impact the behaviour of the development team. </p>
<p>We went from a couple of fat and overdependent classes to many small classes with limited responsibility. This design is not suitable for all scenarios but it is what works well with most Object-Oriented models. If you consider that we are always adding more integration points -it’s an integration project after all- the extra flexibility and explicit concepts are really welcome to the system.</p>
<p>People in the team are more comfortable with the new model, it is easier to talk to the business and understand what they want done. It is also easier for newcomers to understand what the system is about and how to change it –how to map the vocabulary used in story narratives to classes and objects.</p>
<p>Looking at Subversion logs, we can see that commits tend to be contained into a given module. That means fewer conflicts to resolve and less contention –i.e. no or few God classes. In the end of the day this means that developers waste less time waiting for someone else to finish working with a given class and in rework.</p>
<p>On the bad side, making this refactoring while still delivering user stories is messy. It is really important to remember people frequently that we should not patch the old classes, but take the chance to advance towards the new model. </p>
<p>Unfortunately we were not pro-active enough to start refactoring and cleaning the code before having issues with circular dependencies and while playing a story one usually feels much more pressure to just fix the symptom than to solve the root cause.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/O25eLqVTtGs3qge-8HPdGTbwJgs/0/da"><img border="0" ismap="true" src="http://feedads.g.doubleclick.net/~a/O25eLqVTtGs3qge-8HPdGTbwJgs/0/di"/></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/O25eLqVTtGs3qge-8HPdGTbwJgs/1/da"><img border="0" ismap="true" src="http://feedads.g.doubleclick.net/~a/O25eLqVTtGs3qge-8HPdGTbwJgs/1/di"/></a></p><img height="1" src="http://feeds.feedburner.com/~r/fragmental/tw/~4/mb8AjfN-uLA" width="1"/></div>
    </content>
    <updated>2010-03-10T12:56:09Z</updated>
    <published>2010-03-10T12:56:09Z</published>
    <category scheme="http://fragmental.tw" term="agile"/>
    <category scheme="http://fragmental.tw" term="books"/>
    <category scheme="http://fragmental.tw" term="case study"/>
    <category scheme="http://fragmental.tw" term="domain driven design"/>
    <category scheme="http://fragmental.tw" term="everyday tales"/>
    <category scheme="http://fragmental.tw" term="layers"/>
    <category scheme="http://fragmental.tw" term="object orientation"/>
    <category scheme="http://fragmental.tw" term="software architecture"/>
    <category scheme="http://fragmental.tw" term="software design"/>
    <category scheme="http://fragmental.tw" term="trends"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://fragmental.tw/2010/03/10/everyday-tales-anatomy-of-a-refactoring-%e2%80%93-part-3/</feedburner:origlink>
    <author>
      <name>Phillip Calçado</name>
      <uri>http://fragmental.tw</uri>
    </author>
    <source>
      <id>http://fragmental.tw/feed/atom/</id>
      <link href="http://fragmental.tw" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/fragmental/tw" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle xml:lang="en">Repeat after me: Data is code, code is data.</subtitle>
      <title xml:lang="en">Fragmental.tw</title>
      <updated>2010-03-10T12:56:09Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://fragmental.tw/?p=161</id>
    <link href="http://feedproxy.google.com/~r/fragmental/tw/~3/ooDw74oIlV0/" rel="alternate" type="text/html"/>
    <link href="http://fragmental.tw/2010/03/10/everyday-tales-anatomy-of-a-refactoring-%e2%80%93-part-2/#comments" rel="replies" type="text/html"/>
    <link href="http://fragmental.tw/2010/03/10/everyday-tales-anatomy-of-a-refactoring-%e2%80%93-part-2/feed/atom/" rel="replies" type="appication/atom+xml"/>
    <title xml:lang="en">Everyday Tales: Anatomy of a Refactoring – Part 2</title>
    <summary xml:lang="en">Read the first post here.
In the previous post we were facing the problem demonstrated by the diagram below.

Our FacebookMessageParser needs an instance of AllSocialNetworks so that it can create valid Users coming from Facebook. The only implementation we have for the AllSocialNetworks interface is UserRepository, and this implementation needs a FacebookMessageParser. That’s a circular dependency, [...]</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p><a href="http://fragmental.tw/2010/02/24/everyday-tales-anatomy-of-a-refactoring/">Read the first post here.</a></p>
<p>In the previous post we were facing the problem demonstrated by the diagram below.</p>
<p><img alt="" src="http://farm5.static.flickr.com/4045/4384796900_dc59b3cae9_o.jpg"/></p>
<p>Our FacebookMessageParser needs an instance of AllSocialNetworks so that it can create valid Users coming from Facebook. The only implementation we have for the AllSocialNetworks interface is UserRepository, and this implementation needs a FacebookMessageParser. That’s a circular dependency, it becomes impossible to instantiate the objects above without breaking invariants.</p>
<p>The invariant of an object must be always fulfilled; once the invariant is broken the object is not valid anymore and your system is in an abnormal situation –i.e. I would expect it to throw exceptions like crazy and/or eventually die in pain.</p>
<p>The problem seems to be that we don’t have a single place that knows all the required information to create a User. In our system we have a situation where all Users have Facebook accounts, but some of them have Twitter accounts as well. For those with both types of account we must construct the user object with information coming from all Social Networks.</p>
<p> <img alt="" src="http://farm3.static.flickr.com/2718/4421591027_485fd93fa1_o.jpg"/></p>
<p>The first thing we thought about was that our problem was in how the User object was being constructed. One-step instantiation wasn’t working. Turns out that this is a common problem in Object-Orientation, so common that there is an old pattern that deals with it: the <em>Builder</em> design pattern. <a href="http://www.amazon.com/gp/product/0201633612?ie=UTF8&amp;tag=fragmental-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0201633612">One of the consequences of this pattern is</a>:</p>
<blockquote><p>
It gives you finer control over the construction process. Unlike creational patterns that construct products in one shot, the Builder pattern constructs the product step by step under the director’s control. Only when the product is finished does the director retrieve it from the builder. Hence the Builder interface reflects the process of constructing the product more than other creational patterns. This gives you finer control over the construction process and consequently the internal structure of the resulting product.</p></blockquote>
<p>That sounds like exactly what we need here. So we draft a UserBuilder.</p>
<p><img alt="" src="http://farm5.static.flickr.com/4002/4421591105_bbf8e7ae8e_o.jpg"/></p>
<p>This object can be passed to the multiple parsers so that each one of those can populate it with the bit of information that it provides. In the end we call the <em>createUser()</em> method and receive a valid object back.</p>
<p>The next problem: who instantiates the Builder? The UserRepository is supposed to manage the lifecycle for the User, therefore looks like the perfect candidate. What happens, though, when we have a list of users instead of a single one? It sounds that this would be as simple as an operation that maps from one list of Builders to one list of Users:</p>
<p><img alt="" src="http://farm5.static.flickr.com/4018/4421591177_c2c24594c5_o.jpg"/></p>
<p> But the Repository doesn’t know how many Builders should be created -the objects are complex enough so that a UserListBuilder is not an option. Sometimes the FacebookMessageParser is the one who knows how many Users should be created, in other situation the list is known only by the TwitterUserParser.</p>
<p>At that stage our team designed a very complicated strategy that would let the Builders be created in multiple different points depending on the situation. When you get to such complicated solution is possible that you are be missing the point entirely.</p>
<p>We started to realise that our problems may be being made worse given the heavy coupling between parsers, gateways and the Repository. In this post we are looking at only one pair of parser + gateway and it may look like it’s not a big deal, but in the system we had more than ten of those pairs.</p>
<p>The Repositories definitely know a lot more about the internals of each system than they should. Why would it care if Twitter data comes from messages we parse or from objects that we have, say, in cache? It shouldn’t!</p>
<p>The biggest problem that all this coupling was causing in our development process was in our Ubiquitous Language. The business people talked used to say something like <em>“then we get the user profile from Twitter”</em>, but in our heads we had to do the mental mapping –<a href="http://fragmental.tw/2009/03/12/expessive-design-slides/">and mental mapping is bad</a>- between the business lingo and what actually happened inside our model. To reduce the noise we created then objects that represent the systems we talk to.</p>
<p><a href="http://www.flickr.com/photos/pcalcado/4422357620/" title="4.jpg by pcalcado, on Flickr"><img alt="4.jpg" height="202" src="http://farm3.static.flickr.com/2725/4422357620_d26b60981b.jpg" width="500"/></a> </p>
<p>These Facebook and Twitter objects –we called them <em>system abstractions</em>- were modelled after what we, as a business, need from those systems. The technical details about the need to establish a connection and then parse a message were encapsulated by those. We did increase the number of classes, but we reduced the size and complexity of them all.</p>
<p>One of the good things that this refactoring provided was that we could see some interesting patterns in our model that were previously hidden in the messy relationships. Take a look at a subset of the Facebook interface, for example:</p>
<p><a href="http://www.flickr.com/photos/pcalcado/4421591279/" title="5.jpg by pcalcado, on Flickr"><img alt="5.jpg" height="162" src="http://farm5.static.flickr.com/4050/4421591279_88320f11a6_o.jpg" width="441"/></a> </p>
<p>The class that represents Facebook knows about our Users. It receives them as parameters and instantiates that class. Why the hell would Mark Zuckerberg care about our system? What that means, in a practical sense, is that changes that affect only our user have the potential to change our Facebook abstraction. The class changes if the Facebook API changes <strong>or</strong> if User changes. Having more than one reason to change is a smell, <a href="http://www.amazon.com/gp/product/0135974445?ie=UTF8&amp;tag=fragmental-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0135974445">as Uncle Bob says</a>:</p>
<blockquote><p>
Why was it important to separate these two responsibilities into separate classes? The reason is that each responsibility is an axis of change. When the requirements change, that change will be manifest through a change in responsibility among the classes. If a class assumes more than one responsibility, that class will have more than one reason to change.</p>
<p>If a class has more than one responsibility, the responsibilities become coupled. Changes to one responsibility may impair or inhibit the class’s ability to meet the others. This kind of coupling leads to fragile designs that break in unexpected ways when changed.
</p></blockquote>
<p>And that was true. A quick look through SVN history shows that every time there was a change in User we had to change at least one system abstraction -and we have many of those types of classes. In most cases those abstractions that were changed together with User had no real relation with the change being made.</p>
<p>It became clear that each of our third-party systems were actually <em>Bounded Contexts</em>. <a href="http://www.amazon.com/gp/product/0321125215?ie=UTF8&amp;tag=fragmental-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0321125215">In Domain-Driven Design</a>, Bounded Contexts are boundaries that we create around a model to isolate it from other models. We not only define what goes in and what stays out of a model, but we also define how different models relate.</p>
<p>We had already defined that those Bounded Contexts could only be accessed through their system abstraction. What we had to do was to remove the dependency from the third-party Bounded Contexts to our Domain Model. </p>
<p>We are going to see how we approached that in the next post.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/-BbqNrWN4LzbRHVx0LwBXOVvh4A/0/da"><img border="0" ismap="true" src="http://feedads.g.doubleclick.net/~a/-BbqNrWN4LzbRHVx0LwBXOVvh4A/0/di"/></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/-BbqNrWN4LzbRHVx0LwBXOVvh4A/1/da"><img border="0" ismap="true" src="http://feedads.g.doubleclick.net/~a/-BbqNrWN4LzbRHVx0LwBXOVvh4A/1/di"/></a></p><img height="1" src="http://feeds.feedburner.com/~r/fragmental/tw/~4/ooDw74oIlV0" width="1"/></div>
    </content>
    <updated>2010-03-10T12:44:30Z</updated>
    <published>2010-03-10T12:44:30Z</published>
    <category scheme="http://fragmental.tw" term="agile"/>
    <category scheme="http://fragmental.tw" term="books"/>
    <category scheme="http://fragmental.tw" term="case study"/>
    <category scheme="http://fragmental.tw" term="domain driven design"/>
    <category scheme="http://fragmental.tw" term="everyday tales"/>
    <category scheme="http://fragmental.tw" term="layers"/>
    <category scheme="http://fragmental.tw" term="object orientation"/>
    <category scheme="http://fragmental.tw" term="software architecture"/>
    <category scheme="http://fragmental.tw" term="software design"/>
    <category scheme="http://fragmental.tw" term="trends"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://fragmental.tw/2010/03/10/everyday-tales-anatomy-of-a-refactoring-%e2%80%93-part-2/</feedburner:origlink>
    <author>
      <name>Phillip Calçado</name>
      <uri>http://fragmental.tw</uri>
    </author>
    <source>
      <id>http://fragmental.tw/feed/atom/</id>
      <link href="http://fragmental.tw" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/fragmental/tw" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle xml:lang="en">Repeat after me: Data is code, code is data.</subtitle>
      <title xml:lang="en">Fragmental.tw</title>
      <updated>2010-03-10T12:56:09Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-6794675998088145034.post-1557929198340672831</id>
    <link href="http://jupitermoonbeam.blogspot.com/feeds/1557929198340672831/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="https://www.blogger.com/comment.g?blogID=6794675998088145034&amp;postID=1557929198340672831" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/6794675998088145034/posts/default/1557929198340672831" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/6794675998088145034/posts/default/1557929198340672831" rel="self" type="application/atom+xml"/>
    <link href="http://jupitermoonbeam.blogspot.com/2010/03/fear-of-new-how-tdd-and-di-encourage.html" rel="alternate" type="text/html"/>
    <title>Fear of the new (how TDD and DI encourage bad practice)</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">When I first started doing TDD back in the mid-naughties it changed the way I programmed dramatically.  It took me a while to get it at first, how can you test one unit? until I discovered the tricks of dependency injection.  Now my code was shaped in loosely-coupled wonderness and I felt invincible.  I thought I had reached the pinnacle of OOP. Everything suddenly became so easy, it was well tested, easy to change, easy to wrap, swap implementations, decorate, whatever, I was throwing the best design patterns out with such ease that I barely needed to refer to the Gang-of-Four anymore.<br/><br/>I went on in this vein for a good year or so.  And as the millenium's first decade entered early evening and its bright lights began to fade I took a step back and looked at my code.  My god, I thought, this is terrible, what the hell have I been doing? And it was terrible, hundreds of interfaces named somebody's Manager, Persister, Service (oh so many classes called Service), Validator <a href="http://jupitermoonbeam.blogspot.com/2008/09/agent-nouns-are-code-smells.html">etc. etc.</a>, all with a single namesake class implementing them.  There were tens of classes whose purpose seemed to be to co-ordinate these little buggers - for they were little, ten or so lines each (oh how I thought I was doing a grand job) - and they would hand off to other similar classes who co-ordinated other classes and it was turtles all the way down.  And in amongst all of it there were about a dozen classes that had real names like Customer, Account (but even they had interfaces too) and, aye how the sting of memory pains me to this day, they only had getters and setters (it's the shame, you never get over the shame).<br/><br/>It was with great pain I realized for the last year of my professional life I had been producing procedural code with all the idealistic misguided joy of a card holding Russian worker pouring cheap cement to build pointless roads.  I knew the culprit alright: TDD and DI.  I had gone decoupling, unit testing mad.  The result was an irrational fear of the new keyword.  As far as I was concerned the new keyword was banished to the dark depths of Containers, it was a clumsy language feature never to be used again.  But what I had instead was a dependency graph made up almost entirely of stateless singletons.  A simple Ruby script could have replaced every injected dependency with calls to static methods and sure the application would have lost its testability, it would no longer be decoupled, but essentially, at it's essence, and in terms of structure, it would be the same.  TDD and DI had simply given me a fancy way of decoupling static classes.<br/><br/>The new keyword is a wonderful thing.  It lies at the heart of OOP.  Its sole objective is to create a new instance of an object.  If you don't use new you can't create new objects and if you can't create new objects you can't write object orientated code.  And the other fundamental thing about objects is they encapsulate behavior and state.  Singletons don't.  Singletons are procedural.  Regardless of whether they are loosely coupled and injectable.  Real OO classes have private fields (the fewer the better) and methods which do things based on those private fields, sometimes based on arguments passed in, but always, always in the context of those private fields.  And the only way, the one single true way you get values into those private fields is via the constructor and that means using the new keyword.  Let's put it clearly: this '<i>new ValidatedCustomer(customer).IsEmailAddressValid</i>' is OOP. This '<i>c</i><i>ustomerValidator.Validate(customer).IsEmailAddressValid</i>' is procedural.<br/><br/>Now I was writing code using TDD and DI that was object orientated code.  But my fear of the new was still there.  In order to maintain the injectable, loosely-coupled gorgeousness I had begun to do a horrible thing.  I started injecting factories everywhere.  Sure it was an improvement but there was still something horribly smelly going on.  After all the factories were essentially static, singletons whose sole purpose was to delegate to the new statement.  I mean there's single responsibility and then there's craziness!<br/><br/>So I started doing something I thought was really bad: I created objects in my classes! But I wanted to keep loosely coupled and all of that wonderfulness.  This required a dramatic shift in thinking.  Remember when you first did TDD and how it really hurt because you had to structure programs in a different way?  Well it was like doing that all over again.  Every time I started doing something I had to spend half an hour thinking, how do I make this work?  I know I'm right but how?<br/><br/>I learnt a few lessons:<br/><ul><li>Not all classes are about interactions, sometimes they are about results.  Mocking everything out for the sake of it doesn't gain you anything.  Use state based testing to assert the end results not interaction testing to assert what is happening to achieve those results.  </li><li>It's OK for your collaborators to new up something if you ask them, so you can say <i>fileSystem.NewFile(name</i>) if you need to.  </li><li>Collaborators don't always have to be passed in the constructor: they can be passed as arguments to methods as well, so you can say <i>new File('myfile.txt', 'Some text').SaveTo(filesystem)</i>.  </li><li>If a class is unavoidably all boilerplate and co-ordination consider using integration tests, after all mocking the interactions of boilerplate code doesn't tell you anything useful at all.  </li><li>The container shouldn't contain everything, it should be the things that generally require configuration or are likely to change: databases, filesystems, web services etc. Rarely do core domain classes or business principles need to be 'switchable'.</li></ul><div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/6794675998088145034-1557929198340672831?l=jupitermoonbeam.blogspot.com" width="1"/></div></div>
    </content>
    <updated>2010-03-10T11:27:46Z</updated>
    <published>2010-03-10T11:27:00Z</published>
    <author>
      <name>Peter Gillard-Moss</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/10275408277486693139</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-6794675998088145034</id>
      <author>
        <name>Peter Gillard-Moss</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/10275408277486693139</uri>
      </author>
      <link href="http://jupitermoonbeam.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.blogger.com/feeds/6794675998088145034/posts/default" rel="self" type="application/atom+xml"/>
      <link href="http://jupitermoonbeam.blogspot.com/" rel="alternate" type="text/html"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://www.blogger.com/feeds/6794675998088145034/posts/default?start-index=26&amp;max-results=25" rel="next" type="application/atom+xml"/>
      <title>Jupiter Moonbeam &amp; the Geeks from Cyberspace</title>
      <updated>2010-03-13T11:21:54Z</updated>
    </source>
  </entry>

  <entry>
    <id>http://dreamhead.blogbus.com/logs/60290522.html</id>
    <link href="http://dreamhead.blogbus.com/logs/60290522.html" rel="alternate" type="text/html"/>
    <title>走进Scala——伴生对象补遗</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>给《Programming Scala》的作者发邮件澄清一个问题时，我突然意识到<a href="http://dreamhead.blogbus.com/logs/60217908.html" target="_blank">之前写的一些关于伴生对象的说法</a>是基于Scala 2.8的讨论。对于现在的稳定版本2.7还是有一些差异的，于是补遗一篇。<br/><br/>还是上篇的那段代码：<br/>object Companion {<br/>  def show = println("I am a companion")<br/>}<br/><br/>class Companion {<br/>  def shout = Companion.show<br/>}<br/>（Companion.scala）<br/><br/>这次，我们用Scala 2.7编译，然后，反编译：<br/><br/>public class Companion extends java.lang.Object implements scala.ScalaObject{<br/>    public Companion();<br/>    public void show();<br/>    public int $tag()       throws java.rmi.RemoteException;<br/>}<br/><br/>我们忽略$tag()。对比于2.8编译出的版本，show()这个static方法不见了。换句话说，使用2.7编译出来的版本，如果我们想访问show()的话，只能这么写：<br/>  Companion$.MODULE$.show();<br/><br/>放心，虽然作为Java程序员，我们不太习惯这种写法，但这确实是一段可以编译运行的Java代码。<br/><br/>Singleton是没有这样的问题，之前所说的内容还是适用的，我们还是可以用static方法的。从这个角度而言，在Scala 2.7里，Singleton和伴生对象的处理是不统一的，而到了2.8，它们就走到了一起。<br/><br/>不过，在伴生对象的处理上，Scala 2.8还有一个小细节需要注意，如果class和object里有同名的方法，则无法生成static方法。也就是说，如果我们把代码改成这样：<br/>object Companion {<br/>  def show = println("I am a companion")<br/>}<br/><br/>class Companion {<br/>  def show = Companion.show<br/>}<br/><br/>再用Scala 2.8反编译，结果就成了：<br/><br/>public class Companion extends java.lang.Object implements scala.ScalaObject{<br/>    public Companion();<br/>    public void show();<br/>}<br/><br/>这也很容易理解，在Java里面，实例方法和static方法也是不能同名的，不信你试试。<br/><br/>Companion$.MODULE$.show()，虽然这样的写法很诡异，但对于Java操作Scala代码来说，这确实屡试不爽的，无论是字节码是用哪个版本Scala编译出来的。但从软件设计的角度而言，Scala 2.8的实现做了更好的统一，让整个模型更容易理解，是一种更值得推荐的做法。</p><!--sp--><br/><br/><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br/><br/></div>
    </summary>
    <updated>2010-03-10T09:34:01Z</updated>
    <author>
      <name>dreamhead</name>
    </author>
    <source>
      <id>http://dreamhead.blogbus.com</id>
      <logo>http://public.blogbus.com/profile/8/9/0/6098/avatar_6098_96.jpg</logo>
      <link href="http://dreamhead.blogbus.com" rel="alternate" type="text/html"/>
      <link href="http://dreamhead.blogbus.com/index.rdf" rel="self" type="application/rss+xml"/>
      <subtitle>一个小程序员的信口开河</subtitle>
      <title>梦想风暴</title>
      <updated>2010-03-16T05:01:21Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://del.icio.us/brunns#2010-03-09</id>
    <link href="http://feedproxy.google.com/~r/SmallValuesOfCool/~3/3QEDmLxSTiM/brunns" rel="alternate" type="text/html"/>
    <title>Links for 2010-03-09 [del.icio.us]</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><ul>
<li><a href="http://www.panic.com/blog/2010/03/the-panic-status-board/">The Panic Status Board</a><br/>
A nice Big Visible status display</li>
<li><a href="http://www.technologyreview.com/blog/arxiv/24903/?ref=rss">How to build a superluminal computer</a><br/>
Faster than light computing. Awesome. Might even run Ruby at an acceptable speed. ;-)</li>
<li><a href="http://www.beerintheevening.com/pubs/s/51/5173/">Globe, Covent Garden</a></li>
<li><a href="http://news.bbc.co.uk/1/hi/sci/tech/8556585.stm">BBC News - UK Skynet military satellite system extended</a><br/>
Skynet? What's wrong with these people?</li>
<li><a href="http://www.firstcamelsdale.org/">First Camelsdale Cubs</a><br/>
Steve's Django/Pinax site.</li>
<li><a href="http://redline6561.livejournal.com/362393.html">Setting up a Mercurial VCS on Ubuntu</a></li>
<li><a href="http://vagrantup.com/">Vagrant</a><br/>
"Automated creation and provisioning of virtual machines using VirtualBox." Nice.</li>
<li><a href="http://www.b-list.org/weblog/2006/jun/13/how-django-processes-request/">How Django processes a request</a></li>
</ul></div>
    </summary>
    <updated>2010-03-10T08:00:00Z</updated><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://del.icio.us/brunns#2010-03-09</feedburner:origlink>
    <source>
      <id>http://www.brunningonline.net/simon/blog/</id>
      <author>
        <name>Simon Brunning</name>
        <email>simon.brunning+smallvaluescomment@gmail.com</email>
      </author>
      <link href="http://www.brunningonline.net/simon/blog/" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/SmallValuesOfCool" rel="self" type="application/rss+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <rights>Copyright 2010</rights>
      <subtitle>Simon Brunning - stuff that I find interesting</subtitle>
      <title>Small Values of Cool</title>
      <updated>2008-10-08T13:18:28Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.markhneedham.com/blog/?p=2237</id>
    <link href="http://feedproxy.google.com/~r/MarkNeedham/~3/cLEwhvAuP34/" rel="alternate" type="text/html"/>
    <title>Pair Programming: Some thoughts</title>
    <summary>Mark Wilden pointed me to a post he's written about his experience pair programming at Pivotal Labs where he makes some interesting although not uncommon observations.

When you pair program, you're effectively joined at the hip with your pair. You can't pair if only one of you is there.

I've previously written wondering what we should do [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Mark Wilden pointed me to <a href="http://mwilden.blogspot.com/2009/11/why-i-dont-like-pair-programming-and.html">a post he's written about his experience pair programming at Pivotal Labs</a> where he makes some interesting although not uncommon observations.</p>
<blockquote><p>
When you pair program, you're effectively joined at the hip with your pair. You can't pair if only one of you is there.
</p></blockquote>
<p>I've <a href="http://www.markhneedham.com/blog/2009/05/03/pair-programming-when-your-pair-steps-away/">previously written wondering what we should do if our pair isn't around</a> where I was leaning more towards the opinion that we should try to continue along the same path that we were on when working with our pair if they're gone for a short amount of time and to find a new pair or work alone if they're gone for longer.</p>
<p>On the projects I've worked on we'll still have times working alone when there's an odd number of people around or if someone just feels like working on their own and I think that's fine as well. I don't think we need to pair 100% of the time.</p>
<blockquote><p>
You have to be able to think out loud – 8 hours a day. Then you have to type in code while someone is watching you. They'll catch your typos (hopefully after giving you a chance to spot them yourself) and they'll see when you're floundering for how to do something.
</p></blockquote>
<p>I find that this is quite a useful practice for explaining things to yourself although I can see how it would initially exhausting.</p>
<p>Even now there are times when I just want to write some code instead of having to explain what I want to do to someone else. Sadly almost every time I explain something it turns out that my pair has a better idea of how to do it than me so I'm always glad pairing encourages this conversation.</p>
<blockquote><p>
Pair programming doesn't encourage quiet reflection and exploration. You can't just sit back and read some code. You can't just sit and think. I mean, you can, but then your pair is just sitting there.
</p></blockquote>
<p>This is a bit of a double edged sword – pair programming does encourage us to get things done but it's also true that sometimes we need to get the whiteboard out.</p>
<p>Often just sketching out the problem on a piece of paper to check your understanding is enough to trigger a conversation which might result in a better solution.</p>
<p>It does tend to need one person to drive this process though. I haven't seen it just happen organically.</p>
<p>We rarely pair 100% of the time so there are often times when you get a bit of time to play around a bit with the code and see whether specific approaches would work out and I often use this time for reflection and exploration.</p>
<p>One thing which a couple of the commenters on the original blog suggested is that perhaps more rotation was needed to help overcome some of the problems and from my experience it's vital that we do rotate otherwise the pair will end up hating each other!</p>
<p>I recently worked on a story with 3 other people across its life and each person pointed out something that I hadn't previously considered and which led to an eventual output that was much better than it would have been otherwise.</p>
<p>I think <a href="http://www.markhneedham.com/blog/2008/11/04/pair-programming-benefits-of-the-pair-switch-mid-story/">rotating different people onto a story</a> can help lead to more innovative design as long as we have people working together who are relatively flexible and open to trying out new ideas.</p>
<p>Mark's post is certainly interesting though and helps identify some of the things we need to be aware of when pair programming – we don't just want to follow the practice blindly.</p>
<img height="1" src="http://feeds.feedburner.com/~r/MarkNeedham/~4/cLEwhvAuP34" width="1"/></div>
    </content>
    <updated>2010-03-09T23:04:29Z</updated>
    <category term="Pair Programming"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.markhneedham.com/blog/2010/03/09/pair-programming-some-thoughts/</feedburner:origlink>
    <author>
      <name>Mark Needham</name>
    </author>
    <source>
      <id>http://www.markhneedham.com/blog</id>
      <link href="http://www.markhneedham.com/blog" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/MarkNeedham" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Thoughts on Software Development</subtitle>
      <title>Mark Needham</title>
      <updated>2010-03-15T01:04:10Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-35609063.post-1611726168043966667</id>
    <link href="http://www.blogger.com/feeds/35609063/1611726168043966667/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="https://www.blogger.com/comment.g?blogID=35609063&amp;postID=1611726168043966667" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/35609063/posts/default/1611726168043966667" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/35609063/posts/default/1611726168043966667" rel="self" type="application/atom+xml"/>
    <link href="http://iancartwright.com/blog/2010/03/this-blog-has-moved.html" rel="alternate" type="text/html"/>
    <title>This blog has moved</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">This blog is now located at http://blog.iancartwright.com/.
       You will be automatically redirected in 30 seconds, or you may click <a href="http://blog.iancartwright.com/">here</a>.

       For feed subscribers, please update your feed subscriptions to
       http://iancartwright.com/blog/atom.xml.
  <div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/35609063-1611726168043966667?l=iancartwright.com%2Fblog%2Findex.html" width="1"/></div></div>
    </content>
    <updated>2010-03-09T11:31:08Z</updated>
    <published>2010-03-09T11:31:00Z</published>
    <author>
      <name>Ian Cartwright</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/06352508287916298516</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-35609063</id>
      <author>
        <name>Ian Cartwright</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/06352508287916298516</uri>
      </author>
      <link href="http://www.blogger.com/feeds/35609063/posts/default" rel="self" type="application/atom+xml"/>
      <link href="http://iancartwright.com/blog/" rel="alternate" type="text/html"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://www.blogger.com/feeds/35609063/posts/default?start-index=26&amp;max-results=25" rel="next" type="application/atom+xml"/>
      <link href="http://iancartwright.com/blog/atom.xml" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <title>what i still don't know</title>
      <updated>2010-03-09T11:31:08Z</updated>
    </source>
  </entry>

  <entry>
    <id>http://dreamhead.blogbus.com/logs/60217908.html</id>
    <link href="http://dreamhead.blogbus.com/logs/60217908.html" rel="alternate" type="text/html"/>
    <title>走进Scala——伴生对象（Companion Object）</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>准备涉水Scala的Java程序员请注意，Scala里没有static。<br/><br/>在大多数情况下，static真不该是static的。像Scala这样想在面向对象上更进一步的程序设计语言，取消static是一种进取的表现，这样得以保证了其面向对象模型的完整性。好吧，我承认，有时候，我们还是需要类一级的属性和操作的。在Scala里，我们还是有机会的，这便是伴生对象（Companion Object）的作用。<br/><br/>下面就是一个伴生对象的例子：<br/><br/>object Companion {<br/>  def show = println("I am a companion")<br/>}<br/><br/>class Companion {<br/>  def shout = Companion.show<br/>}<br/>（Companion.scala）<br/><br/>这个object就是我们所说的伴生对象，如果读过《<a href="http://dreamhead.blogbus.com/logs/58331783.html" target="_blank">走进Scala——Singleton</a>》，你会觉得这个伴生对象和Singleton异曲同工，实际上，是这样的。伴生对象本身就是一个Singleton，不同的是，它有一个与之同名的类（这里的class Companion），二者可以相互访问彼此的私有成员。在这里，我们暂且不关心私有成员的相互访问。<br/><br/>编译一下：<br/>  scalac Companion.scala<br/><br/>同Singleton一样，我们也得到了两个文件：Companion.class和Companion$.class。我们还可以用javap查看反编译的结果，其中，Companion$.class与之前的Singleton$.class几近相同，这里就省略了。一起来看看Companion.class。<br/>  javap Companion<br/><br/>public class Companion extends java.lang.Object implements scala.ScalaObject{<br/>    public static final void show();<br/>    public Companion();<br/>    public void shout();<br/>}<br/><br/>因为有了对应的class，object成了伴生对象。从结果可以看出，伴生对象和它对应的类在字节码层面走到了一起（Companion类）。换句话说，在Scala里面的class和object在Java层面里面合二为一，class里面的成员成了实例成员，object成员成了static成员。我们已经知道，这里的static成员只是一个简单的wrapper，封装了实际的操作。<br/><br/>对应到反编译的代码上，我们看到了与object相关的那个static方法——show。因为要构建Companion的实例，所以，生成的代码里有构造函数。此外，class Companion的实例方法shout在字节码层面上也体现到了Companion类里。<br/><br/>至此，我们已经对伴生对象有了一个基本的了解。在Scala的层面上，我们把分属于类和实例分开放置，从代码的组织而言，会更加清晰。在实现层面上，它们都是按照对象处理的（分别用Companion$和Companion），从而达到了对象模型的统一。<br/><br/>最后，我想说，请善用object。</p><!--sp--><br/><br/><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br/><br/></div>
    </summary>
    <updated>2010-03-09T09:10:31Z</updated>
    <author>
      <name>dreamhead</name>
    </author>
    <source>
      <id>http://dreamhead.blogbus.com</id>
      <logo>http://public.blogbus.com/profile/8/9/0/6098/avatar_6098_96.jpg</logo>
      <link href="http://dreamhead.blogbus.com" rel="alternate" type="text/html"/>
      <link href="http://dreamhead.blogbus.com/index.rdf" rel="self" type="application/rss+xml"/>
      <subtitle>一个小程序员的信口开河</subtitle>
      <title>梦想风暴</title>
      <updated>2010-03-16T05:01:21Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>http://del.icio.us/brunns#2010-03-08</id>
    <link href="http://feedproxy.google.com/~r/SmallValuesOfCool/~3/_2g6vx5rbKs/brunns" rel="alternate" type="text/html"/>
    <title>Links for 2010-03-08 [del.icio.us]</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><ul>
<li><a href="http://www.wimbledonguardian.co.uk/news/5046943.Work_to_start_on_most_hated_building_in_Colliers_Wood_/?ref=rss">Work to start on most hated building in Colliers Wood?</a></li>
<li><a href="http://en.wikipedia.org/wiki/Yo_La_Tengo">Yo La Tengo</a></li>
</ul></div>
    </summary>
    <updated>2010-03-09T08:00:00Z</updated><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://del.icio.us/brunns#2010-03-08</feedburner:origlink>
    <source>
      <id>http://www.brunningonline.net/simon/blog/</id>
      <author>
        <name>Simon Brunning</name>
        <email>simon.brunning+smallvaluescomment@gmail.com</email>
      </author>
      <link href="http://www.brunningonline.net/simon/blog/" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/SmallValuesOfCool" rel="self" type="application/rss+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <rights>Copyright 2010</rights>
      <subtitle>Simon Brunning - stuff that I find interesting</subtitle>
      <title>Small Values of Cool</title>
      <updated>2008-10-08T13:18:28Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-8528631747209969303.post-2356563979431505133</id>
    <link href="http://docondev.blogspot.com/feeds/2356563979431505133/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="http://docondev.blogspot.com/2010/01/what-if-no-one-reads-it.html#comment-form" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default/2356563979431505133" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default/2356563979431505133" rel="self" type="application/atom+xml"/>
    <link href="http://docondev.blogspot.com/2010/01/what-if-no-one-reads-it.html" rel="alternate" type="text/html"/>
    <title>What if no one reads it?</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><h4>You should favor readability</h4>Among the books I am currently making my way through is "Exploring Computer Science with Scheme" by Oliver Grillmeyer. The publish date on this particular book is 1998. No matter how often it happens, I feel a twinge of despair for our profession when I read sound advice from a decade or more ago that has yet to be widely adopted; or worse is still hotly contested.<br/><br/>Grillmeyer contrasts a couple different functions that accomplish the same end. One terse, but obfuscated; One verbose, but transparent. In conclusion, Grillmeyer states, "In a tradeoff between readability and length of code, you should favor readability."<br/><br/><blockquote class="yellow">Damn straight.</blockquote><br/>Sure, you can use some Ruby-fu and get those four lines in the controller down to one. Yes, you can in-line the whole damn method call. But to what end? For what purpose? Why are you reducing the lines of code? What is your objective?<br/><br/><h4>Favoring line count</h4>I once completed the Bowling Kata in Ruby. It was approximately twenty five lines of code. It was readable. Each method had a clear and singular intent. I asked a non-developer friend to look at it and tell me what it did. It took him no more than 60 seconds to figure it out. I then told a Ruby developer about the Kata and without even looking at the code he said, "You should be able to do that in seven lines of Ruby."<br/><br/>So I set out to refactor the code down to seven lines. And it was an interesting exercise. I managed to get the code down to about twelve lines; I had cut the code in half. But then I stopped. The intent was no longer clear. One had to interpret the code in order to discern what was happening. My tests were a mess; I could not test behaviors in isolation.<br/><br/><blockquote class="blue">I had sacrificed clarity at the altar of line count. And I was ashamed.</blockquote><br/><h4>A (very brief) twitter discussion</h4>So after reading the line from Grillmeyer, <a href="http://twitter.com/DocOnDev/status/7203910473" target="_blank">I tweeted it</a>. Moments later, <a href="http://bit.ly/5wipzv" target="_blank">a buddy responded</a>.<br/><br/><h4>What if no one reads it?</h4>Interesting question.<br/><br/>So you're working on a pet project; something that only you will ever work on. No other developer will ever see this code. And you're working on a feature where the desired behavior is so well known and immutable that you too will never, ever, under any circumstances need to change it. And the language and platform are absolutes; they too will never change - no new libraries, no change in any of your dependencies; not even a revision tick. You are certain that no one will read it; not even you.<br/><br/>And you can either write it in a terse manner, or a readable manner (but not both). Which is better?<br/><br/>Good code is efficient. Good code is testable. Good code displays an attention to detail. Good code has singular purpose and lacks duplication. Good code is expressive. Good code is written by developers who care. Good code is pleasing to read. Good Code is <a href="http://blog.objectmentor.com/articles/2008/04/08/clean-code-whew">Clean Code</a>.<br/><br/>Having worked on a system that manages over one hundred thousand purchases per day, I do not believe there are many situations which absolutely mandate performance at the cost of readability. So while I expect the argument, I believe it to be an outlier at best, if not completely fictional.<br/><br/>Given the definition of good code and the likelihood that what we are working on does not require obfuscated code for performance gains, there is no other possible consideration.<br/><br/>Code must be written for readability. If it is not; it is not good code.<br/><br/>Certainly, one can opt to knowingly write bad code, but I cannot comprehend the motive.<br/><br/><br/><br/><br/><br/><div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/8528631747209969303-2356563979431505133?l=docondev.blogspot.com" width="1"/></div></div>
    </content>
    <updated>2010-03-09T06:07:49Z</updated>
    <published>2010-01-02T16:31:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="Development"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Testing"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Rant"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Programming Practices"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="Kata"/>
    <author>
      <name>DocOnDev</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/17064897772691908215</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-8528631747209969303</id>
      <author>
        <name>DocLogic</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/09149149882666714621</uri>
      </author>
      <link href="http://docondev.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default" rel="self" type="application/atom+xml"/>
      <link href="http://docondev.blogspot.com/" rel="alternate" type="text/html"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default?start-index=26&amp;max-results=25" rel="next" type="application/atom+xml"/>
      <subtitle>Michael Norton (doc) is a Development Manager living in Wadsworth, OH. Michael's experience covers a wide range of development topics. Michael declares expertise in no single language or methodology and is immediately suspicious of anyone who declares such expertise.</subtitle>
      <title>Doc On Dev</title>
      <updated>2010-03-15T01:40:13Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-8528631747209969303.post-5150818970049710974</id>
    <link href="http://docondev.blogspot.com/feeds/5150818970049710974/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="http://docondev.blogspot.com/2010/02/contributing-to-project-you-find-on.html#comment-form" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default/5150818970049710974" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default/5150818970049710974" rel="self" type="application/atom+xml"/>
    <link href="http://docondev.blogspot.com/2010/02/contributing-to-project-you-find-on.html" rel="alternate" type="text/html"/>
    <title>Contributing to a project you find on GitHub</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">For the purpose of this article, I assume you have <a href="http://git-scm.com/">git</a> installed, have a <a href="https://github.com/">GitHub</a> account, and are fundamentally familiar git.<br/><br/>You've been <a href="http://github.com/explore">exploring GitHub</a> and have discovered a project you want to contribute to. Let's say it is<a href="http://github.com/DocOnDev/functional-koans"> my fork of the Functional Koans</a>. You want to add some flair to the Python Koans in particular.<br/><br/><h4>Fork the DocOnDev project</h4><br/>To create a fork, press the "fork" button on the project's page.<br/><br/><div class="separator" style="text-align: center;"><a href="http://4.bp.blogspot.com/_9BSWFzzwekI/S4hjdTsYV3I/AAAAAAAAACM/ejnK8Kk2Zbs/s1600-h/GitHub-Fork.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/_9BSWFzzwekI/S4hjdTsYV3I/AAAAAAAAACM/ejnK8Kk2Zbs/s320/GitHub-Fork.png"/></a></div><br/>When the fork is complete, you will have a copy of the project in your repositories listing.<br/><div class="separator" style="text-align: center;"><a href="http://4.bp.blogspot.com/_9BSWFzzwekI/S4g62TlElSI/AAAAAAAAAB0/f51RnhnmSKA/s1600-h/GitHub-Fork-New-Repo.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/_9BSWFzzwekI/S4g62TlElSI/AAAAAAAAAB0/f51RnhnmSKA/s320/GitHub-Fork-New-Repo.png"/></a></div><h4>Clone your project</h4>Now you need to clone your fork. Make sure you use the “Your Clone URL” and not the “Public Clone URL”. You want to be able to push changes back to your own repository.<br/><b><br/></b><br/><pre class="brush: bash">$ git clone git@github.com:[your-github-account]/functional-koans.git<br/></pre><br/>Once the clone is complete your repo will have a remote named “origin” that points to your fork on github. You will use "origin" for your own regular activities.<br/><h4>Get the source</h4>Let's make sure we have the python source.<br/><br/><pre class="brush: bash">$ cd functional-koans<br/>$ git checkout -b python<br/>$ git pull origin python<br/>From git@github.com:[your-github-account]/functional-koans<br/> * branch            python    -&gt; FETCH_HEAD<br/>Auto-merging README.markdown<br/>CONFLICT (add/add): Merge conflict in README.markdown<br/>Automatic merge failed; fix conflicts and then commit the result.</pre><br/>Ugh. File conflict. No worries, open the file and edit it to look like this:<br/><br/><pre class="brush: text"># Functional Koans<br/><br/><br/>### About the Koans<br/><br/>There are several functional languages that have contributed their own<br/>versions of the koans.  Each language has it's own branch with<br/>detailed instructions on how to get started.<br/><br/>### Getting Started<br/><br/>To get the koans for a particular language, simply clone the repo and<br/>checkout the branch:<br/><br/>'git clone git://github.com/relevance/functional-koans.git' <br/>'git checkout branch -b [branch_name]'<br/>'git pull origin [branch_name]'<br/><br/><br/>where [branch_name] is the name of the branch (language) you want to<br/>work on.  To get a list of all branches run:<br/><br/>'git branch -a'<br/></pre><br/>Now add the changed file to the python branch and check it in<br/><br/><pre class="brush: bash">$ git add README.markdown<br/>$ git commit -m'Fixed README conflict'</pre><h4>Add a remote to the original project</h4>First, switch back to the master branch locally.<br/><pre class="brush: bash">$ git checkout master</pre>Then let's take a look at all of our branches.<br/><pre class="brush: bash">$ git branch -a<br/>* master<br/>  python<br/>  origin/FSharp<br/>  origin/HEAD<br/>  origin/clojure<br/>  origin/master<br/>  origin/scala</pre>We see that the origin (your repository) has all of the branches, but our local repository only has master and python. The asterisk next to master indicates this is our active branch.<br/><br/>Let's add another remote that points to the source you originally forked from. You can call this remote anything you want. I suggest you use something that makes sense to you. In GitHub's examples, they use the name "upstream", but that I find that to be too general. I tend to name this remote after the original account I forked from. So for the sake of this example, we will use my convention:<br/><br/><pre class="brush: bash">$ git remote add DocOnDev git://github.com/DocOnDev/functional-koans.git<br/></pre><br/>You may have noticed that we used the public clone URL for DocOnDev. Truth is, he probably won't give you access to push changes directly to his repository anyway. I heard he's a real jerk about that stuff. And if he had given you access to push directly to his repo, why did you create a fork...?<br/><br/><h4>Just to be sure...</h4>Ok, so we just forked the code, but let's make sure we have the absolute latest version from DocOnDev before we start hacking away. We are going to fetch the latest from DocOnDev. Fetch grabs the latest source from all branches in DocOnDev's functional-koans repo and brings them down to us.<br/><br/><pre class="brush: bash">$ git fetch DocOnDev<br/>From git://github.com/DocOnDev/functional-koans<br/> * [new branch]      FSharp     -&gt; DocOnDev/FSharp<br/> * [new branch]      clojure    -&gt; DocOnDev/clojure<br/> * [new branch]      master     -&gt; DocOnDev/master<br/> * [new branch]      python     -&gt; DocOnDev/python<br/> * [new branch]      scala      -&gt; DocOnDev/scala<br/></pre><br/>Now if we take another look at the branches...<br/><br/><pre class="brush: bash">$ git branch -a<br/>* master<br/>  python<br/>  origin/FSharp<br/>  origin/HEAD<br/>  origin/clojure<br/>  origin/master<br/>  origin/python<br/>  origin/scala<br/>  DocOnDev/FSharp<br/>  DocOnDev/clojure<br/>  DocOnDev/master<br/>  DocOnDev/python<br/>  DocOnDev/scala<br/></pre><br/><h4>Make your changes</h4>You are now free to make your changes and updates. You can add functionality, refactor, whatever it was that inspired you to contribute to this project in the first place.<br/><br/>Make sure you are cognizant of the various branches. Don't make changes in python branch, switch to master branch, and commit unless you absolutely intend to add the file to the master branch. Check in early and often. And of course, write your tests first. ;)<br/><br/>Check in every so often and fetch (or pull) any changes DocOnDev may have committed.<br/><pre class="brush: bash">$ git checkout python<br/>$ git fetch DocOnDev python<br/>From git://github.com/DocOnDev/functional-koans<br/> * branch            python     -&gt; FETCH_HEAD<br/></pre><br/><h4>Request a Pull</h4>You've completed your changes and you'd like DocOnDev to take a look at them and consider them for addition to the project. Simply navigate to your fork and use the "Pull Request" button. You can explain your changes to DocOnDev as a part of the request.<br/><div class="separator" style="text-align: center;"><a href="http://3.bp.blogspot.com/_9BSWFzzwekI/S4hgxKyUYWI/AAAAAAAAAB8/pkreZr2aWPk/s1600-h/GitHub-Pull-Request.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/_9BSWFzzwekI/S4hgxKyUYWI/AAAAAAAAAB8/pkreZr2aWPk/s320/GitHub-Pull-Request.png"/></a></div><br/>And that's the basics of it. It may take a while to get used to working on a project with multiple branches and multiple committers. I know I hozed my repo more than once before I got the hang of it.<br/><br/><br/><br/><br/><br/><br/><br/><br/><div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/8528631747209969303-5150818970049710974?l=docondev.blogspot.com" width="1"/></div></div>
    </content>
    <updated>2010-03-09T04:21:22Z</updated>
    <published>2010-02-27T00:03:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="Development"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="git"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="How To"/>
    <author>
      <name>DocOnDev</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/17064897772691908215</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-8528631747209969303</id>
      <author>
        <name>DocLogic</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/09149149882666714621</uri>
      </author>
      <link href="http://docondev.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default" rel="self" type="application/atom+xml"/>
      <link href="http://docondev.blogspot.com/" rel="alternate" type="text/html"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://www.blogger.com/feeds/8528631747209969303/posts/default?start-index=26&amp;max-results=25" rel="next" type="application/atom+xml"/>
      <subtitle>Michael Norton (doc) is a Development Manager living in Wadsworth, OH. Michael's experience covers a wide range of development topics. Michael declares expertise in no single language or methodology and is immediately suspicious of anyone who declares such expertise.</subtitle>
      <title>Doc On Dev</title>
      <updated>2010-03-15T01:40:13Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-US">
    <id>tag:gigix.thoughtworkers.org,2010-03-09:1026</id>
    <link href="http://gigix.thoughtworkers.org/2010/3/9/readings-on-beach" rel="alternate" type="text/html"/>
    <title xml:lang="en-US">沙滩阅读记录</title>
    <content type="xhtml" xml:lang="en-US"><div xmlns="http://www.w3.org/1999/xhtml"><p>Buzz是个好东西。一边玩Buzz，一边抓紧时间看了几本书。</p>


	<p><a href="http://www.douban.com/subject/2138463/">Organizational Patterns</a> 操作性缺缺，看完仍然不知道该怎么实施──甚至不知道能不能实施</p>


	<p><a href="http://www.douban.com/subject/1924212/">说话的魅力</a> 废话超过文化</p>


	<p><a href="http://www.douban.com/subject/3313363/">演说之禅</a> “胶片”这个词真的很不好，因为它杂糅了幻灯片和讲义</p>


	<p><a href="http://www.douban.com/subject/3137158/">让你的声音更有魅力</a> 系统性和可操作性都太差了，国人写书的通病</p>


	<p>还在读 <a href="http://www.douban.com/subject/2776967/">Fearless Change</a> 。原来Linda Rising就是模式年鉴的作者，难怪我听着那么耳熟呢。</p>


	<p>Evangelist =&gt; Test the Waters =&gt; Time for Reflection =&gt; Small Successes =&gt; Step by Step</p>


	<p>Ask for Help, Connector, Guru on Your Side, Innovator, and Just Say Thanks</p>


	<p>You’ve had a meeting using the pattern Piggyback or Brown Bag. Perhaps you were able to Do Food and you scheduled the meeting at The Right Time. You brought some interesting books or articles, hoping to Plant the Seeds and point to External Validation for your new idea. You talked about the Next Steps for your fledgling effort and maybe you used e-Forum to help Stay in Touch with people who are getting interested in your work. If you were really lucky, your collection of like-minded folks has started to form a Group Identity.</p>


	<p>昨天收到 <a href="http://www.douban.com/subject/2075510/">Strength Finder 2.0</a> 。</p>


	<p>You might be especially adept at legal work, crafting sound business deals, or ensuring compliance to regulations.</p>


	<p>郭晓说：I am surprised by Harmony!</p>


	<p>伤了。</p></div>
    </content>
    <updated>2010-03-09T01:32:21Z</updated>
    <published>2010-03-09T01:20:00Z</published>
    <author>
      <name>gigix</name>
    </author>
    <source>
      <id>tag:gigix.thoughtworkers.org,2010:mephisto/</id>
      <link href="http://gigix.thoughtworkers.org/feed/rss2.xml" rel="self" type="application/atom+xml"/>
      <link href="http://gigix.thoughtworkers.org/" rel="alternate" type="text/html"/>
      <title xml:lang="en-US">透明思考 - Thoughts</title>
      <updated>2010-03-12T16:02:32Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.markhneedham.com/blog/?p=2230</id>
    <link href="http://feedproxy.google.com/~r/MarkNeedham/~3/mW67FyAba0E/" rel="alternate" type="text/html"/>
    <title>Getting real: Book review</title>
    <summary>I recently came across 37 Signals 'Getting Real' book where they go through their approach to building web applications and there have certainly been some good reminders and ideas on the best way to do this.
These are some of my favourite parts:

Ship it!

If there are minor bugs, ship it as soon you have the core [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I recently came across 37 Signals '<a href="http://gettingreal.37signals.com">Getting Real</a>' book where they go through their approach to building web applications and there have certainly been some good reminders and ideas on the best way to do this.</p>
<p>These are some of my favourite parts:</p>
<ul>
<li><strong>Ship it!</strong><br/>
<blockquote><p>
If there are minor bugs, ship it as soon you have the core scenarios nailed and ship the bug ﬁxes to web gradually after that. The faster you get the user feedback the better.
</p></blockquote>
<p>Often on projects I've worked on we've taken the approach that bugs get worked on before new stories which makes sense in a way because it means that we are fixing problems quickly and keeping the quality of the application high.</p>
<p>In reality what often happens is that low priority bugs just end up not getting looked at but I like the fact that we can choose to make that an explicit approach rather than just allowing it to happen to us.</p>
<blockquote><p>
Prioritize your bugs (and even ignore some of them) </p>
<p>Just because you discover a bug in your product, doesn’t mean it’s time to panic. All software has bugs – it’s just a fact of life.
</p></blockquote>
<p>I find it interesting that there might be more value in getting something out the door and then getting feedback on it rather than spending extra time perfecting it up front.
</p></li>
<li><strong>Fix Time and Budget, Flex Scope</strong><br/>
<blockquote><p>
You have to ﬁgure out what’s really important. What’s going to make it into this initial release? This forces a constraint on you which will push you to make tough decisions instead of hemming and hawing.
</p></blockquote>
<p>From my experience a lot of times we end up implementing features just because that's what was agreed in the initial release plan and there is often a reluctance to change that even if a feature isn't really that useful  anymore.</p>
<p>It becomes even more problematic if we get to the stage where it's not possible to deliver all the features promised in the remaining time so it certainly makes sense to me that in that situation we would look to focus on getting the absolutely essential things in first.</p>
</li>
<li><strong>Choose any enemy</strong><br/>
<blockquote><p>
Sometimes the best way to know what your app should be is to know what it shouldn’t be. Figure out your app’s enemy and you’ll shine a light on where you need to go.
</p></blockquote>
<p>This seems to be a much better idea than just copying the ideas of your competitor which might seem the obvious thing to do if you're working in the same area.</p>
<p>The problem with that approach of course is that when you do copy you have no actual vision of what you're doing with your application anyway so you'll always be playing catch up.
</p></li>
<li><strong>Don't overcomplicate the application</strong>
<p>There are a few parts of the book where the authors talk about keeping the application simple and then letting the users play with it:</p>
<blockquote><p>
The harder we tighten things down, the less room there is for a creative, emergent solution. Whether it’s locking down requirements before they are well understood or prematurely optimizing code, or inventing complex navigation and workﬂow scenarios before letting end users play with the system, the result is the same: an overly complicated, stupid system instead of a clean, elegant system that harnesses emergence. </p>
<p>Keep it small. Keep it simple. Let it happen.
</p></blockquote>
<p>Andrew Hunt, The Pragmatic Programmers</p>
<p>The users can then decide for us where we need to fill in more details:</p>
<blockquote><p>
Details reveal themselves as you use what you’re building. You’ll see what needs more attention. You’ll feel what’s missing. You’ll know which potholes to pave over because you’ll keep hitting them. That’s when you need to pay attention, not sooner.
</p></blockquote>
<p>In particular they suggest that focusing on very specific details about the page layout/colour/wording can be left until later because it will only serve to hinder forward progress if we concentrate on it too early.
</p></li>
<li><strong>Scaling an application</strong><br/>
<blockquote><p>
You don’t have a scaling problem yet </p>
<p>“Will my app scale when millions of people start using it?” </p>
<p>Ya know what? Wait until that actually happens.
</p></blockquote>
<p>On several projects that I've worked on there often seems to be a desire to focus on performance and scaling an application very early on which seems wasteful when we could be focusing on actually building something that has so many users that we need to scale it later on. I think this advice is spot on.
</p></li>
<li><strong>Write less software</strong>
<p>A common theme throughout the book is that of writing less software to achieve our goals:</p>
<blockquote><p>
The best designers and the best programmers…are the ones that can determine what just doesn’t matter. </p>
<p>That’s where the real gains are made. </p>
<p>Most of the time you spend is wasted on things that just don’t matter. If you can cut out the work and thinking that just don’t matter, you’ll achieve productivity you’ve never imagined.
</p></blockquote>
<blockquote><p>
Innovation is not about saying yes to everything. It’s about saying NO to all but the most crucial features. </p>
<p>Throw away customer feature requests – if they're really important then they'll come back anyway</p>
<p>Don’t worry about tracking and saving each request that comes in. Let your customers be your memory. If it’s really worth remembering, they’ll remind you until you can’t forget.
</p></blockquote>
<p>The authors ideas around preferences were particularly interesting to me:</p>
<blockquote><p>
Preferences are also evil because they create more software. </p>
<p>More options require more code. And there’s all the extra testing and designing you need to do too.
</p></blockquote>
<p>I hadn't appreciated until recently quite how much complexity we can add to an application by allowing users to play around with the display of information on a screen.</p>
<p>It seems like a nice feature to have but it would be interesting to see statistics that could tell us what percentage of users actually that type of thing when it's not the core idea of the application.</p>
<p>I also quite liked the following and I think it's something that we need to do more often on teams:</p>
<blockquote><p>
Encourage programmers to make counteroﬀers.You want to hear: “The way you suggested will take 12 hours. But there’s a way I can do it that will only take one hour. It won’t do x but it will do y.” Let the software push back. Tell programmers to fight for what they think is the best way.
</p></blockquote>
</li>
<li><strong>Decisions are temporary so make the call and move on</strong><br/>
<blockquote><p>
So don’t do the “paralysis through analysis” thing. That only slows progress and saps morale. </p>
<p>Instead, value the importance of moving on and moving forward. Get in the rhythm of making decisions. Make a quick, simple call and then go back and change that decision if it doesn’t work out.
</p></blockquote>
<p>I think a big part of this is getting the mentality that it's fine to make changes after we've 'finished' something. Any other approach doesn't work from my experience.</p>
</li>
<li><strong>Reduce meetings</strong><br/>
<blockquote><p>
Meetings usually arise when a concept isn’t clear enough. Instead of resorting to a meeting, try to simplify the concept so you can discuss it quickly via email or im or Campﬁre.
</p></blockquote>
<p>I find it interesting that they prefer communicating by email because I've often found that it's not the best communication mechanism since it's really easy to misinterpret what people mean.</p>
<p>Having said that if we can make concepts clearer and the need for a meeting is an indicator that we need to do that then perhaps we can still meet in person and just make the meeting much shorter.
</p></li>
<li><strong>Design the interface before you start programming</strong><br/>
<blockquote><p>
Too many apps start with a program-ﬁrst mentality. That’s a bad idea. Programming is the heaviest component of building an app, meaning it’s the most expensive and hardest to change. Instead, start by designing ﬁrst.
</p></blockquote>
<p>I've certainly fallen into this trap a lot but I've been trying to follow the <a href="http://www.infoq.com/presentations/bdd-dan-north">outside in approach</a> more strictly recently and so far I'm finding that it reduces the feedback cycle quite substantially which is only a good thing.
</p></li>
<li><strong>Design for regular, blank, and error states </strong><br/>
<blockquote>
<p>For each screen, you need to consider three possible states: </p>
<p>Regular<br/>
The screen people see when everything’s working ﬁne and your app is ﬂush with data. </p>
<p>Blank<br/>
The screen people see when using the app for the ﬁrst time, before data is entered. </p>
<p>Error<br/>
The screen people see when something goes wrong.
</p></blockquote>
<p>I'd never even though of this at all and I'm certainly guilty of only ever considering applications when all the data is filled in so this is certainly something else to consider.
</p></li>
<li><strong>Tear down the walls between support and development </strong><br/>
<blockquote><p>In the restaurant business, there’s a world of diﬀerence between those working in the kitchen and those out front who deal with customers. It’s important for both sides to understand and empathize with the other. That’s why cooking schools and restaurants will often have chefs work out front as waiters so the kitchen staff can interact with customers and see what it’s actually like on the front lines.
</p></blockquote>
<p>My colleague Chris Read and some others seem to be trying to close this gap with the <a href="http://www.devopsdays.org/">devops</a> movement which also has <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=331">a track at QCon London</a> this week.</p>
<p>The idea of working in support to see what an application is like from that perspective is something that more experienced colleagues often recommend although I've not done it as yet.
</p></li>
</ul>
<p>Overall I found this book a really interesting and quick read and although many of the ideas suggested seem like common sense it's strange that we often don't do all of them. </p>
<p>The 37 Signals guys also have a new book coming out in the UK tomorrow titled '<a href="http://www.amazon.co.uk/Rework-Meetings-One-Down-Competition-Greatness/dp/0091929784/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1268085360&amp;sr=8-1">Rework</a>' which sounds like it could be quite a good read as well.</p>
<img height="1" src="http://feeds.feedburner.com/~r/MarkNeedham/~4/mW67FyAba0E" width="1"/></div>
    </content>
    <updated>2010-03-08T21:56:58Z</updated>
    <category term="Software Development"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.markhneedham.com/blog/2010/03/08/getting-real-book-review/</feedburner:origlink>
    <author>
      <name>Mark Needham</name>
    </author>
    <source>
      <id>http://www.markhneedham.com/blog</id>
      <link href="http://www.markhneedham.com/blog" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/MarkNeedham" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Thoughts on Software Development</subtitle>
      <title>Mark Needham</title>
      <updated>2010-03-15T01:04:10Z</updated>
    </source>
  </entry>

  <entry>
    <id>http://martinfowler.com/bliki/VcsSurvey.html</id>
    <link href="http://martinfowler.com/bliki/VcsSurvey.html" rel="alternate" type="text/html"/>
    <title>Bliki: VcsSurvey</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>When I discussed <a href="http://martinfowler.com/bliki/VersionControlTools.html">VersionControlTools</a> I said that it
  was an unscientific agglomeration of opinion. As I was doing it I
  realized that I could add some spurious but mesmerizing numbers to
  my analysis by doing a survey. Google's spreadsheet makes the
  mechanics of conducting a survey really simple, so I couldn't
  resist.</p><img src="http://martinfowler.com/bliki/images/vcsSurvey/summary.png"/><p>I conducted the survey from February 23 2010 until March 3 2010
  on the ThoughtWorks software development mailing list. I got 99
  replies. In the survey I asked everyone to rate a number of version
  control tools using the following options:</p><ul><li>Best in Class:   Either the best VCS or equal best</li><li>OK: Not the best, but you're OK with it.</li><li>Problematic: You would argue that the team really ought to be using something else</li><li>Dangerous: This tool is really bad and ThoughtWorks should press hard to have it changed</li><li>No opinion: You haven't used it</li></ul><p>The results were this:</p>
<table class="data"><tbody><tr><th>Tool</th><th>Best</th><th>OK</th><th>Problematic</th><th>Dangerous</th><th>No
  Opinion</th><th>Active Responses</th><th>Approval %</th></tr><tr><td>Subversion</td><td>20</td><td>72</td><td>6</td><td>1</td><td>0</td><td>99</td><td>93%</td></tr><tr><td>git</td><td>65</td><td>19</td><td>1</td><td>0</td><td>14</td><td>85</td><td>99%</td></tr><tr><td>Mercurial</td><td>33</td><td>27</td><td>2</td><td>0</td><td>36</td><td>62</td><td>97%</td></tr><tr><td>ClearCase</td><td>0</td><td>3</td><td>14</td><td>41</td><td>41</td><td>58</td><td>5%</td></tr><tr><td>TFS</td><td>0</td><td>0</td><td>32</td><td>22</td><td>44</td><td>54</td><td>0%</td></tr><tr><td>CVS</td><td>0</td><td>14</td><td>59</td><td>11</td><td>15</td><td>84</td><td>17%</td></tr><tr><td>Bazaar</td><td>1</td><td>13</td><td>3</td><td>0</td><td>80</td><td>17</td><td>82%</td></tr><tr><td>Perforce</td><td>1</td><td>26</td><td>16</td><td>1</td><td>54</td><td>44</td><td>61%</td></tr><tr><td>VSS</td><td>1</td><td>1</td><td>11</td><td>64</td><td>22</td><td>77</td><td>3%</td></tr></tbody></table>
<p>As well as the raw summary values, I've added two calculated
columns here to help summarize the results.</p><ul><li>Active Responses: The total of responses excluding "No
  Opinion". (eg for git: 65 + 19 + 1 + 0)</li><li>Approval %: The sum of best and ok responses divided by active
  responses, expressed as a percentage. (eg for git: (65 + 19) / 85)</li></ul><p>The graph shows a scatter plot of approval percentage and active
responses. As you can see there's a clear cluster around Subversion,
git, and Mercurial with high approval and a large amount of
responses. It's also clear that there's a big divide in approval between those
three, together with Bazaar and Perforce, versus the rest.</p><p>Although the graph captures the headline information well, there's
a couple of other subtleties I should mention.</p><ul><li>Although the trio of Subversion, git, and Mercurial cluster close
together on approval, git does get a notably higher amount of best
scores: (65 versus 20 and 33).</li><li>VSS got the most "dangerous" responses, but a couple of people
 approved of it.</li><li>Neither TFS or ClearCase are liked much, but ClearCase got more
"dangerous" responses than TFS (41 versus 22).</li><li>Don't read too much into small differences as I'm sure they aren't
significant. I'm sure the difference in approval percentage between VSS, TFS,
and ClearCase isn't signifcant, but the difference between these three
and the leaders is.</li></ul><p>Some caveats. This is a survey of opinion of ThoughtWorkers who
follow our internal software development discussion list, nothing more. It's
possible some of them may have been biased by my previous article
(although unlikely, since I've never managed to get my ThoughtBot
opinion-control software to work reliably). Opinions of tools are
often colored by processes that are more about the organization than
the tool itself. But despite these, I think it's an interesting data
point.</p><p>I should also stress the important point to take away from this
isn't the comparison between those close in the numbers, eg comparing
git and Mercurial or comparing TFS and ClearCase. Any survey like this
has a certain amount of noise in it, and I suspect the noise here is
greater than such a difference. The important point is the big
approval gap between the leading tools (Subversion, git, and
Mercurial) and the laggards - essentially the point in
<a href="http://martinfowler.com/bliki/VersionControlTools.html">VersionControlTools</a>.</p></div>
    </content>
    <updated>2010-03-08T19:02:00Z</updated>
    <category term="tools"/>
    <source>
      <id>http://martinfowler.com/feed.atom</id>
      <author>
        <name>Martin Fowler</name>
        <email>fowler@acm.org</email>
        <uri>http://martinfowler.com</uri>
      </author>
      <link href="http://martinfowler.com/feed.atom" rel="self" type="application/atom+xml"/>
      <link href="http://martinfowler.com" rel="alternate" type="text/html"/>
      <subtitle>Master feed of news and updates from martinfowler.com</subtitle>
      <title>Martin Fowler</title>
      <updated>2010-03-08T19:02:00Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://www.dancingmango.com/blog/?p=850</id>
    <link href="http://feedproxy.google.com/~r/Dancingmango/~3/Hot-rz4x4LY/" rel="alternate" type="text/html"/>
    <title>Petition</title>
    <summary>I’ve written in the past about the government’s abysmal track record on IT development.  I met with the local MP to discuss the issues but he didn’t really get it; he sent me away to write a policy paper for him which I really had time for…  So good news that someone is doing something [...]</summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I’ve <a href="http://www.dancingmango.com/blog/2009/03/12/someone-should-talk-to-the-minister-about-agile/" target="_self">written in the past about the government’s abysmal track record</a> on IT development.  I met with the local MP to discuss the issues but he didn’t really get it; he sent me away to write a policy paper for him which I really had time for…  So good news that <a href="http://blog.robbowley.net/2010/02/09/a-call-to-action-to-uk-software-developers-to-stop-your-money-being-wasted/" target="_blank">someone is doing something about it </a>with a petition on the <a href="http://petitions.number10.gov.uk/ITProcessReview/" target="_blank">Number 10 website</a>.</p>
<p>In his recent update on the progress of the petition, <a href="http://blog.robbowley.net/2010/03/04/government-it-process-review-petition-update/" target="_blank">Rob Bowley</a> mentions the Rural Payments Agency project.  I can’t attest to either have been an ‘expert’ or to have had a salary anything near what he mentions, but I was a consultant on that project so nod in informed agreement.  That experience gave me a benchmark to compare ‘bad’ ways of going about an IT project to compare with the ‘good’ world of lean and agile that I now inhabit.</p>
<p><a href="http://petitions.number10.gov.uk/ITProcessReview/" target="_blank">Please sign the petition</a>.</p>
<img height="1" src="http://feeds.feedburner.com/~r/Dancingmango/~4/Hot-rz4x4LY" width="1"/></div>
    </content>
    <updated>2010-03-08T12:58:14Z</updated>
    <category term="Agile"/>
    <category term="Methodology"/>
    <category term="project management"/>
    <category term="government"/>
    <category term="lean"/>
    <category term="petition"/>
    <category term="waste"/>
    <category term="mentions"/>
    <category term="update"/>
    <category term="compare"/>
    <category term="salary"/>
    <category term="inhabit"/>
    <category term="abysmal"/>
    <category term="bowley"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.dancingmango.com/blog/2010/03/08/850/</feedburner:origlink>
    <author>
      <name>marc</name>
    </author>
    <source>
      <id>http://www.dancingmango.com/blog</id>
      <link href="http://www.dancingmango.com/blog" rel="alternate" type="text/html"/>
      <link href="http://feeds.feedburner.com/Dancingmango" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>It's all about the human experience</subtitle>
      <title>dancingmango</title>
      <updated>2010-03-13T02:03:54Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-8396317.post-3785220748080964641</id>
    <link href="http://www.learninggeneralist.com/feeds/3785220748080964641/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="https://www.blogger.com/comment.g?blogID=8396317&amp;postID=3785220748080964641" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/8396317/posts/default/3785220748080964641?v=2" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/8396317/posts/default/3785220748080964641?v=2" rel="self" type="application/atom+xml"/>
    <link href="http://feedproxy.google.com/~r/blogspot/sawZ/~3/WQWlNBrsbfQ/call-for-participation-xp-2010.html" rel="alternate" type="text/html"/>
    <title>Call for Participation - XP 2010</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><img alt="" height="413" src="http://dl.dropbox.com/u/478762/Xp2010%20flyer.png" title="" width="560"/><br/> I'm speaking at the <a href="http://xp2010.org/">11th International Conference on Agile Software Development, XP2010</a><br/><span style="font-weight: bold;">Dates:</span> 1-4 June 2010, Trondheim, Norway<br/><span style="font-weight: bold;">Early registration deadline:</span> 24 March 2010<br/><br/>XP is a leading international conference on agile methods in software and information systems development. XP 2010 will bring together software and information systems professionals, both researchers and practitioners, to discuss the latest trends, applications, and theory, share experiences, and reveal new research results in agile software development.<br/><br/>XP2010 features a full four-day program of up to nine parallel tracks with Tutorials, Workshops, Experience Reports, Research Presentations, Invited Industry Talks, Lightning Talks, Open Space, Posters, and a Doctoral Symposium<br/><br/>This year's keynote speakers are:<br/><br/><span style="font-weight: bold;">Scott Page (University of Michigan Ann Arbor)</span>: Leveraging Diversity in Parallel: Perspective, Heuristics, and Oracles<br/><br style="font-weight: bold;"/><span style="font-weight: bold;">David Anderson (David J Anderson &amp; Associates, Seattle, Washington)</span>: Catalyzing Lean: Building a Limited WIP Society in Your Organization<br/><br/><span style="font-weight: bold;">Bjørn Alterhaug (NTNU) &amp; John Pål Inderberg (NTNU):</span> Improvisation: Between Panic and Boredom Perspectives on teamwork, dialogue and presence in music and other contexts<br/><br/>XP2010 will be held in Trondheim, which is Norway's third largest municipality.  Trondheim is a Norwegian center of education, technical and medical research with the Norwegian University of Science and Technology (NTNU) and SINTEF located in the city. NTNU has about 25,000 students. The conference will be at the Rica Nidelven hotel. On the riverbed floor of the hotel you will find the conference section with airy meeting rooms, all with wireless internet access, natural daylight and a view of the Nidelven river.  A thousand years ago the Viking King Olav Tryggvason sailed up this river before founding his seat of government in Trondheim.  For the fourth year in a row the Rica Nidelven Hotel has been presented with the award for Norway's best breakfast. Over 400 hotels in Norway compete annually for this award, which is judged by a panel of top chefs from Norway and Twinings.<br/><br/>For an overview of topics and presentations, please see the conference program at <a href="http://xp2010.org/">http://xp2010.org/</a>.<div class="blogger-post-footer">© Sumeet Moghe, 2009<img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/8396317-3785220748080964641?l=www.learninggeneralist.com" width="1"/></div></div>
    </content>
    <updated>2010-03-08T11:27:21Z</updated>
    <published>2010-03-08T11:21:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="xp2010"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.learninggeneralist.com/2010/03/call-for-participation-xp-2010.html</feedburner:origlink>
    <author>
      <name>Sumeet Moghe</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/15085919050832112976</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-8396317</id>
      <logo>http://creativecommons.org/images/public/somerights20.gif</logo>
      <author>
        <name>Sumeet Moghe</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/15085919050832112976</uri>
      </author>
      <link href="http://www.learninggeneralist.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.learninggeneralist.com/" rel="alternate" type="text/html"/>
      <link href="http://www.blogger.com/feeds/8396317/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" rel="next" type="application/atom+xml"/>
      <link href="http://feeds.feedburner.com/blogspot/sawZ" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://creativecommons.org/licenses/by-nc-sa/3.0/" rel="license" type="text/html"/>
      <subtitle>If you always do what you've always done, you'll always get what you always got and there is always more</subtitle>
      <title>Free as in Freedom</title>
      <updated>2010-03-14T08:01:15Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-8396317.post-7685628902687625799</id>
    <link href="http://www.learninggeneralist.com/feeds/7685628902687625799/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="https://www.blogger.com/comment.g?blogID=8396317&amp;postID=7685628902687625799" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/8396317/posts/default/7685628902687625799?v=2" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/8396317/posts/default/7685628902687625799?v=2" rel="self" type="application/atom+xml"/>
    <link href="http://feedproxy.google.com/~r/blogspot/sawZ/~3/gBdunL1hEA8/innovation-in-enterprise-is-too-much.html" rel="alternate" type="text/html"/>
    <title>Innovation in the Enterprise -- is too much experience a good thing?</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><img alt="" src="http://farm4.static.flickr.com/3202/2941374416_6904eee7d1.jpg" style="margin: 0pt auto 10px; display: block; text-align: center;" title="From london_ally under Creative Commons"/>From <a href="http://en.wikipedia.org/wiki/101_Zen_Stories">Wikipedia</a>:  <br/><span style="font-style: italic;">Nan-in, a Japanese master , received a university professor who came to inquire about Zen.</span><br style="font-style: italic;"/><span style="font-style: italic;">Nan-in served tea. He poured his visitor's cup full, and then kept on pouring.</span><br style="font-style: italic;"/><span style="font-style: italic;">The professor watched the overflow until he no longer could restrain himself. "It is overfull. No more will go in!"</span><br style="font-style: italic;"/><span style="font-style: italic;">"Like this cup," Nan-in said, "you are full of your own opinions and speculations. How can I show you Zen unless you first empty your cup?"</span><br/><br/>I've been thinking about this for a few days -- does increasing experience in a company eventually stifle innovation? Why do younger, smaller companies seem to innovate more than large organisations with years of experience?<br/><br/>I've often felt that when a company is young, there are a lot of people with less experience who usually jump at most new ideas. There are those with a vision for the company that support these new ideas. Yes, there are pragmatists, conservatives and skeptics who may not be as gung-ho about new ideas, but in the initial days of the company, they're outnumbered by the enthusiastic lot and eventually they convert. It seems as if ideas flow in a viral fashion in these organisations.<br/><br/>Fast forward a decade and a half and a lot of the innovators are now grizzled professionals. The visionaries have learned from their mistakes and are more risk-aware. Yes, there are new innovators, but because of the shift of the original enthusiasts, the company now has a larger number of people with their own set ideas of success and with a strong criticism for every new idea. They've got experience to know why specific ideas will fail, they know that they'd rather not experiment and invite risk! As it turns out, new ideas get beaten down even as they're mentioned. People spend so much time trying to justify their ideas, that when it's time for implementation, they've lost all their steam. As a consequence, innovation suffers.<br/><br/>I have seen this phenomenon myself, but I don't know what organisations do to get out of such situations. Any thoughts?<br/><br/><font size="1">(<span style="font-weight: bold;">Photo credit:</span> <a href="http://www.flickr.com/photos/london_ally/">london_ally</a> under the <a href="http://creativecommons.org">Creative Commons</a>)</font><div class="blogger-post-footer">© Sumeet Moghe, 2009<img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/8396317-7685628902687625799?l=www.learninggeneralist.com" width="1"/></div></div>
    </content>
    <updated>2010-03-07T15:41:53Z</updated>
    <published>2010-03-07T15:41:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="organizational culture"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="collaboration"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="enterprise 2.0"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="innovation"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="human resources"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.learninggeneralist.com/2010/03/innovation-in-enterprise-is-too-much.html</feedburner:origlink>
    <author>
      <name>Sumeet Moghe</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/15085919050832112976</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-8396317</id>
      <logo>http://creativecommons.org/images/public/somerights20.gif</logo>
      <author>
        <name>Sumeet Moghe</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/15085919050832112976</uri>
      </author>
      <link href="http://www.learninggeneralist.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.learninggeneralist.com/" rel="alternate" type="text/html"/>
      <link href="http://www.blogger.com/feeds/8396317/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" rel="next" type="application/atom+xml"/>
      <link href="http://feeds.feedburner.com/blogspot/sawZ" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://creativecommons.org/licenses/by-nc-sa/3.0/" rel="license" type="text/html"/>
      <subtitle>If you always do what you've always done, you'll always get what you always got and there is always more</subtitle>
      <title>Free as in Freedom</title>
      <updated>2010-03-14T08:01:15Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-8396317.post-8432275383138845866</id>
    <link href="http://www.learninggeneralist.com/feeds/8432275383138845866/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="https://www.blogger.com/comment.g?blogID=8396317&amp;postID=8432275383138845866" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/8396317/posts/default/8432275383138845866?v=2" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/8396317/posts/default/8432275383138845866?v=2" rel="self" type="application/atom+xml"/>
    <link href="http://feedproxy.google.com/~r/blogspot/sawZ/~3/VXYFfg1QIZo/cant-collaborate-without-being.html" rel="alternate" type="text/html"/>
    <title>No Collaboration without Colocation? Maybe you're not 'Agile enough'!</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><img alt="" src="http://dl.dropbox.com/u/478762/distribution.jpg" style="margin: 0pt auto 10px; display: block; text-align: center;" title=""/><br/>As I await my flight to London, a strange thought possesses me. How much of Agile is valid today? A lot of <a href="http://en.wikipedia.org/wiki/Agile_software_development">Agile</a> practices are almost a decade old. Since then, the enterprise collaboration landscape has changed significantly, team dynamics have changed quite a bit and dare I say the market is a lot more mature, having been through two relatively bad periods. This has always made me feel that to be Agile, you almost need to be 'not really Agile'. After all, the dictionary meaning of 'agile' seems to be:<br/><pre><span style="font-weight: bold;">agile |ˈajəl|</span><br/>adjective<br/>able to move quickly and easily : Ruth was as agile as a monkey | <br/>figurative his vague manner concealed an agile mind.</pre>Well if that's the case, I feel like it's almost outdated to believe that a lack of colocation has to eventually mean a lack of collaboration and communication. Well there's no doubt that a colocated team in a team room will most likely generate great discussion, that said we've got technology today that can <a href="http://agilecoach.typepad.com/agile-coaching/2009/09/distributed-agile-in-a-virtual-world.html">simulate team room like environments even without having people colocated</a>. I say that a truly Agile team is so passionate about communication that they'll end up being resourceful enough to generate more communication in a distributed mode!<br/><h3>It's not that you can't communicate<br/></h3>The fact is that today, more so than ever, the world is really, really flat. The notions of distance are almost becoming irrelevant with the advent of what some people are calling webvolution. Yes, there's not much one can do about 12 hour time differences. That being said, there's been significant advances in technology to ensure that if there's a fair overlap in timezones, teams can collaborate almost seamlessly without having to bother about colocation. <a href="http://twitter.com/dineshtantri">Dinesh</a> and I recently submitted a proposal to <a href="http://agile2010.agilealliance.org">Agile 2010</a> to demonstrate how we're seeing teams adapt their way of working to ensure that distribution doesn't mean disaster! Here's a table from the proposal that indicates the various tool types that you have at your disposal to create rich communication within teams, distributed or not! Using a combination of enterprise social software and tools on the public internet, teams can actually make distribution seem much easier than we've traditionally made it out to be. Of course, there are some common sense considerations to distribution -- take a look at <a href="http://offshore.thoughtworks.com/can-you-hear-me-now">Mark Rickmeier's recorded talk</a> for more information.<br/><br/><table border="1" width="100%"><tbody><tr><td style="text-align: center;"><b>Tools - How?</b></td><td style="text-align: center;"><b>Potential Implication - What?</b></td><td style="text-align: center;"><b>Agile Practice - Where can this be used?</b></td></tr><tr><td>Blogs</td><td>Personal knowledge management, Learning and reflection, provides opportunity to convert potential ties into actual ties</td><td>Team knowledge bases. Organisation wide knowledge sharing. Iteration reports. Daily Handoffs. Project timelines</td></tr><tr><td>Wikis</td><td>Project/Product Documentation, Co-Authoring learning</td><td>Retrospectives, Negotiating Requirements/Stories, “Handovers” across time zones</td></tr><tr><td>Workstreams - Microblogging</td><td>Ambient Awareness - Who knows what?</td><td>Standups, Distributed Dev Huddles, “Handovers” across time zones</td></tr><tr><td>Social Bookmarking</td><td>Knowledge Sharing</td><td>Particularly in the area of cross-project knowledge sharing and organisational knowledge bases</td></tr><tr><td>Social Networking</td><td>Serendipity</td><td>Finding experts in the organisation, leveraging weak ties, building relationships with potential problem solvers</td></tr><tr><td>Prediction Markets</td><td>Crowdsource complex decisions/outcomes - Estimation, likely release dates,</td><td>Estimation, Release Planning (this is one which we’re yet to see in practice)</td></tr><tr><td>Idea Management Platforms</td><td>Ongoing improvement to practices</td><td>Brainstorming, Design decisions</td></tr><tr><td>Web Conferencing Tools</td><td>Distributed pairing/reviews/</td><td>Distributed Pairing, showcases, training, workshops, really all sorts of meetings</td></tr><tr><td>Virtual Worlds</td><td>Virtual Offices, Realistic distributed simulations, synchronous learning, shared workspaces</td><td>All sorts of meetings, team room, Retrospectives, (There’s a <a href="http://agilecoach.typepad.com/agile-coaching/2009/09/distributed-agile-in-a-virtual-world.html" id="ql_r" title="state farm case study">state farm case study</a> for this)</td></tr><tr><td>Video Conferencing</td><td>Meetings</td><td>IPM’s, Retrospectives</td></tr><tr><td>Collaborative Software Development Environments</td><td>Contextual Collaboration (one-stop collaboration platform)</td><td>All kinds of practices, but particularly improving on communication and visibility.</td></tr></tbody></table><br/><h3>You just need to communicate differently</h3>Now you may argue that while the tools have been there for a while your mileage has been different. I don't deny that possibility. I don't even deny the fact that your communication may not have been as rich as what you've seen when you communicated face to face. This though, is not a problem with the tool -- it's a paradigm shift that we need to adjust to. Just like we say today,<span style="font-style: italic;"> "What did we do before Google?"</span> we will say in 2020 <span style="font-style: italic;">"What did we do before the social web?"</span>. The change is destined to happen -- but before that we need to adjust ourselves to the context of the platform. I relate this to how we change our communication in various cultural contexts -- a conversation on the streets in England is significantly different to a conversation on the streets of India. Similarly, we adjust our style of travel based on the context; we change our style of eating based on the context too. So why not think of communication in a similar manner?<br/><br/>Conversations are great, but think of the value a facilitative tool like Google Wave brings you. The collaborative nature of tools such as Wave ensures that people like me who have a loud voice and can be extremely overbearing don't get an opportunity to derail the conversation. As a corollary, people who generally take time to get their thoughts organised or those that are generally shy, have the opportunity to now make their point in peace. Now to make best use of the medium, you need to appreciate these advantages and commit yourself to the context. In a similar manner, I believe webinars are far more facilitative than a face to face classroom session. In classrooms, people have to hold on to their thoughts for the fear of disturbing the sage on stage. In webinars OTOH, people can air their thoughts freely and without reserve at any given time. Now you may not be able to talk face to face, but can you communicate better - hell yeah! Take a look at some of the webinars from the <a href="http://learntrends.ning.com/page/learntrends-2009-november">virtual, free LearnTrends conference last year</a>, if you don't believe me. As I always say, <span style="font-style: italic;">"<a href="http://www.learninggeneralist.com/2009/11/learning-to-learn-in-modern-enterprise.html">The social web is more facilitative than facilitation!"</a></span>. You can keep making the comparisions and I suspect that if you're fair, you'll reach the same conclusions.<br/><h3>The future is so bright, I should wear shades!</h3><img alt="" src="http://www.ubereyes.org/images/oversized-christian-dior-black-sunglasses_14.jpg" style="margin: 0pt auto 10px; display: block; text-align: center;" title=""/>The coming years promise a lot in terms of enterprise collaboration. I was recently reading Karl Kapp and Tony Driscoll's <a href="http://learningin3d.info/">Learning in 3D</a>, and the way the world is progressing towards the <a href="http://www.thinkbalm.com/immersive-internet/">immersive internet</a>, it could mean great things for society in general. Better collaboration platforms will mean lesser travel and hence a smaller carbon footprint. The diminishing need for colocation will mean that working moms, people in underprivileged countries can work in the best firms without having to leave their homes -- a great diversity boon for the industry! The fact that people will be able to work from their homes means that companies can spend less money on facilities and channel saved funds towards better pay and new business -- good news for all of us! The future is very, very bright indeed! <hr/>As a knowledge worker, the possibilities of the webvolution really excite me. I believe big things can happen if we can change our perspectives slightly. What do you think? Let me know by adding your comments to this post. Hope you enjoyed today's article!<div class="blogger-post-footer">© Sumeet Moghe, 2009<img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/8396317-8432275383138845866?l=www.learninggeneralist.com" width="1"/></div></div>
    </content>
    <updated>2010-03-07T13:46:48Z</updated>
    <published>2010-03-07T01:45:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="agile"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="distributed agile"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="collaboration"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="enterprise 2.0"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="learning"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="communication"/><feedburner:origlink xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.learninggeneralist.com/2010/03/cant-collaborate-without-being.html</feedburner:origlink>
    <author>
      <name>Sumeet Moghe</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/15085919050832112976</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-8396317</id>
      <logo>http://creativecommons.org/images/public/somerights20.gif</logo>
      <author>
        <name>Sumeet Moghe</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/15085919050832112976</uri>
      </author>
      <link href="http://www.learninggeneralist.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.learninggeneralist.com/" rel="alternate" type="text/html"/>
      <link href="http://www.blogger.com/feeds/8396317/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" rel="next" type="application/atom+xml"/>
      <link href="http://feeds.feedburner.com/blogspot/sawZ" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <link href="http://creativecommons.org/licenses/by-nc-sa/3.0/" rel="license" type="text/html"/>
      <subtitle>If you always do what you've always done, you'll always get what you always got and there is always more</subtitle>
      <title>Free as in Freedom</title>
      <updated>2010-03-14T08:01:15Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-21992362.post-113743870613045579</id>
    <link href="http://blog.sriramnarayan.com/2010/03/pair-programming-payoff.html#comment-form" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/21992362/posts/default/113743870613045579?v=2" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/21992362/posts/default/113743870613045579?v=2" rel="self" type="application/atom+xml"/>
    <link href="http://blog.sriramnarayan.com/2010/03/pair-programming-payoff.html" rel="alternate" type="text/html"/>
    <title>Pair Programming Payoff</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><div style="text-align: justify;">For a project that runs for, say six months or more, there should no extra development cost on account of pair programming. Period. If there is extra cost, it means pairing is not paying off for you. Pairing should pay off in the following difficult-to-measure ways:</div><ol style="text-align: justify;"><li>Lesser rework during development on account of misunderstood/ill-defined requirements. These things surface quickly when pairs talk to each other.</li>
<li>Slight reduction in maintenance cost on account of clearer code. Because every line is now considered readable by at least two people. (more in case of pair rotation)</li>
<li>A better detail level design results when each pair acts as a sounding board for the other. Good design reduces cost of future change.</li>
<li>Faster/better process of bringing new team members up to speed.</li>
<li>Lesser impact of people taking vacations.</li>
<li>Lesser bugs in QA, UAT</li>
<li>More hours of focused work per day - however professional someone may be it is natural for concentration to wax and wane. Pairing almost always helps here. </li>
<li>Unlike the case of no-pairing, there is no separate code-review activity required<br/>
</li>
</ol><div style="text-align: justify;"><br/>
</div><div style="text-align: justify;">How do you figure if there is extra cost? Estimate both ways. The total 'release-lifecycle effort' for the case of pairing should not exceed that of no-pairing. Individual stories may indicate greater effort but that is okay. It is very difficult to do controlled experiments to nail this down. There are some <a href="http://scholar.google.com/scholar?q=pair+programming+study&amp;hl=en&amp;safe=off&amp;esrch=BetaShortcuts&amp;um=1&amp;ie=UTF-8&amp;oi=scholart" id="npxf" title="studies">studies</a> but your mileage may vary. </div><div style="text-align: justify;"><br/>
</div><div style="text-align: justify;">A word of caution when estimating for such comparisons. Remember that on all real projects, actuals mostly exceed estimates. Some of the difference is borne by the client (change control etc) and the rest by the vendor (unpaid overtime etc). You need to have a realistic idea of effort overrun for the case of no-pairing to be able to compare it with the overrun for the case of pairing.</div><div style="text-align: justify;"><br/>
</div><div style="text-align: justify;">If pairing is resulting in net higher development cost on a long running project, then it simply means (to paraphrase Kent Beck) that the client is getting XP'd on :)</div><div class="blogger-post-footer"><p style="text-align: right;"><a href="http://blog.sriramnarayan.com">blog home page</a></p><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/21992362-113743870613045579?l=blog.sriramnarayan.com" width="1"/></div><img height="1" src="http://feeds.feedburner.com/~r/XploringAround/~4/lduBmsaNZ8g" width="1"/></div>
    </content>
    <updated>2010-03-07T12:36:05Z</updated>
    <published>2010-03-04T07:19:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="agile-antipatterns"/>
    <author>
      <name>Sriram</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/01237485664035584743</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-21992362</id>
      <author>
        <name>Sriram</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/01237485664035584743</uri>
      </author>
      <link href="http://blog.sriramnarayan.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://blog.sriramnarayan.com/" rel="alternate" type="text/html"/>
      <link href="http://www.blogger.com/feeds/21992362/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;orderby=published&amp;v=2" rel="next" type="application/atom+xml"/>
      <link href="http://feeds.feedburner.com/XploringAround" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Sriram Narayan's blog on IT</subtitle>
      <title>XPloring around</title>
      <updated>2010-03-16T04:58:29Z</updated>
    </source>
  </entry>

  <entry>
    <id>http://dreamhead.blogbus.com/logs/60061451.html</id>
    <link href="http://dreamhead.blogbus.com/logs/60061451.html" rel="alternate" type="text/html"/>
    <title>翻译《Programming Scala》</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>三个半月前的一个周末，<a href="http://dreamhead.blogbus.com/logs/51970577.html" target="_blank">我开始翻译《Programming Scala》</a>。时至今日，基本上接近尾声了，只剩下最后的一些细节需要修订了。<br/><br/>对我而言，翻译这本书的最初目的就是为了学习Scala，译初稿的时候，劲头大得很，每天抓紧上班之前、午休和下班之后的时间，充分利用周末。赶在时间进入2010年之前，就完成了10章的翻译，而整本书才14章。原本和<a href="http://dear.blogbus.com/" target="_blank">小刀</a>约定一人一半的，我一不小心抢了小刀的买卖，不过最后，我额外的又抢了他的一章。做咨询项目一向累心，那段时间，翻译成了我调剂心情的一种方式。<br/><br/>初译是痛快的，但就像写程序一样，跑得快了，难免会忽略很多东西。翻译经验丰富的小刀在把关，他经常会挑出很多问题，有些被我不经意带过的细节都会被他揪出来，让我觉得甚是惭愧。中间有几次，他甚至拒绝review我的稿子，因为有很多话读起来都不那么连贯，这让我无地自容。回过头来看那些稿子，除了认同他，我别无选择，他的认真让我的懈怠无处遁形。<br/><br/>review就没有初译来得爽快了，经常为了一句话需要纠结很长时间，而且有了小刀的认真在前，为了不再让他鄙视，只有再仔细一点。进度大大放慢了，加上过年回家休息，一个多月翻译的稿子，用了差不多两个月才重新又过了一遍。直到今天，才又一次读到这本书的末尾，又一次看到“Thank you for reading.”。<br/><br/>从前，读翻译过来的书时，偶尔会抱怨，换作我，可能会比他翻译的好。走过这三个多月，我相信了，翻译是一件费力不讨好的事。自己理解和翻译出来根本就不是一回事，而且，一旦交稿，就不由自己说得算了。<br/><br/>翻译这本书，我个人的目标——学习Scala已经达成了。至于这本书的质量，让人看过之后去评判吧！</p><!--sp--><br/><br/><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br/><br/></div>
    </summary>
    <updated>2010-03-07T09:12:12Z</updated>
    <author>
      <name>dreamhead</name>
    </author>
    <source>
      <id>http://dreamhead.blogbus.com</id>
      <logo>http://public.blogbus.com/profile/8/9/0/6098/avatar_6098_96.jpg</logo>
      <link href="http://dreamhead.blogbus.com" rel="alternate" type="text/html"/>
      <link href="http://dreamhead.blogbus.com/index.rdf" rel="self" type="application/rss+xml"/>
      <subtitle>一个小程序员的信口开河</subtitle>
      <title>梦想风暴</title>
      <updated>2010-03-16T05:01:21Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-6892448840767296959.post-8802926723207844016</id>
    <link href="http://findingbugs.blogspot.com/feeds/8802926723207844016/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="http://findingbugs.blogspot.com/2010/03/oh-that-innocent-looking-page.html#comment-form" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/6892448840767296959/posts/default/8802926723207844016" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/6892448840767296959/posts/default/8802926723207844016" rel="self" type="application/atom+xml"/>
    <link href="http://findingbugs.blogspot.com/2010/03/oh-that-innocent-looking-page.html" rel="alternate" type="text/html"/>
    <title>Oh That Innocent Looking Page !</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><div><br/></div><div>So, you are building a web application that talks to bunch of other applications, shared databases and other web services which aren't in your control. Sounds like a typical project, isn't it ? :-)</div><div><br/></div><div>Well, I was the (only) tester in such a project sometime back. Maintaining a working test environment was a pain. Broken connectivity between dependent applications, databases was a recurring problem. To make my life as well as environment team's life easy, developers came up with this idea.</div><div><br/></div><div><i>A simple html page that shows the connection status of different web services, databases in test environment.</i></div><div><br/></div><div>When it was introduced in mid release cycle, I was happy :-) Now I don't have to worry much when the transactions aren't going through. Just check the status page, if any connectivity is broken, shout across to Environment team, get the things fixed. Life is simple and worry free !</div><div><br/></div><div>We decided to introduce the same status page to Production System as well, with limited access, only to environment team. After all, it made all of our lives easy.</div><div><br/></div><div>So, moving on to 'Go Live' Day. We run the deploy scripts, I run the sanity tests, things were looking good.</div><div><br/></div><div>In a matter of an hour or so, environment team got in touch with us, apparently production systems were receiving a huge volume of data. At first shot, it looked like our application is the originator of the traffic.</div><div><br/></div><div>So, we had to take our application down (luckily it was on a weekend, not much work going on) while we debug the issue.</div><div><br/></div><div>The way status page was supposed to work was to send a 'Are you up?' question to different systems and was expecting a 'Yes' or 'No' answer. But one of the shared library we used had a bug. Instead of sending a response, it sent back a request, for which our application promptly sent a response. This got into an infinite loop, hence the surge in the traffic. Well, the problem was quickly solved and we went home anyway, albeit little late.</div><div><br/></div><div>Apparently same thing was happening in Test environment, but me being the only user, there wasn't much havoc. It went unnoticed.</div><div><br/></div><div>This incident got me in to thinking.</div><div><br/></div><div>You see, I, as a tester, am worried about the stories, functionality and bunch of other things like performance and security. I wouldn't doubt much about these small tools we use that make our work easy. Big mistake.</div><div><br/></div><div>As a 'only' tester in my team, it's my responsibility to check every new thing that's being introduced in to the application. I should be on the top of the things, questioning and doubting every little piece of software that gets developed.</div><div><br/></div><div>So, a lesson learnt: Never ever look at a piece of software and think it's harmless. Not even a simple innocent looking html page.</div><div><br/></div><div><a href="http://www.urbandictionary.com/define.php?term=tldr">TL;DR</a> : I goofed up in testing, learnt a lesson.</div><div><br/></div><div>:-)</div><div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/6892448840767296959-8802926723207844016?l=findingbugs.blogspot.com" width="1"/></div></div>
    </content>
    <updated>2010-03-07T00:04:48Z</updated>
    <published>2010-03-05T05:07:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="Testing Techniques"/>
    <author>
      <name>**Sri Harsha**</name>
      <email>srimaiya@gmail.com</email>
      <uri>http://www.blogger.com/profile/13127034293643327734</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-6892448840767296959</id>
      <author>
        <name>**Sri Harsha**</name>
        <email>srimaiya@gmail.com</email>
        <uri>http://www.blogger.com/profile/13127034293643327734</uri>
      </author>
      <link href="http://findingbugs.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.blogger.com/feeds/6892448840767296959/posts/default" rel="self" type="application/atom+xml"/>
      <link href="http://findingbugs.blogspot.com/" rel="alternate" type="text/html"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>A Tester's thoughts about testing :)</subtitle>
      <title>** Tester's Thoughts **</title>
      <updated>2010-03-09T19:48:45Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-23529072678094516.post-3048560790116607983</id>
    <link href="http://elhumidor.blogspot.com/feeds/3048560790116607983/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="https://www.blogger.com/comment.g?blogID=23529072678094516&amp;postID=3048560790116607983" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/23529072678094516/posts/default/3048560790116607983?v=2" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/23529072678094516/posts/default/3048560790116607983?v=2" rel="self" type="application/atom+xml"/>
    <link href="http://elhumidor.blogspot.com/2010/03/actionscript-const-gotcha.html" rel="alternate" type="text/html"/>
    <title>ActionScript const Gotcha</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I've been working in ActionScript lately. It's a bizarre language. Java-style OO features are smashed right on top of JavaScript, with no regard for the prototype-based inheritance that the language has had all along. (As far as I can tell Adobe doesn't want you to think about prototypes. I haven't dug into how the Java-style ActionScript class model plays with the prototype model, but it might be worth exploring.)</p>

<p>After a few years of full-time Ruby, the adjustment has been pretty painful. One of my biggest complaints is the verbosity of the static type declarations. Having recently spent some time playing around with Scala, I was incredibly impressed at how much noise can be removed from a statically typed language with a compiler that does good type-inference. The ActionScript compiler does absolutely zero type-inference, and the result makes for really nasty reading.</p>

<p>One of the additions to JavaScript syntax that initially impressed me was the introduction of the <code>const</code> keyword. I really appreciate how Scala's <code>val</code> keyword makes declaration of immutable fields just as terse and clear as the <code>var</code> keyword does for mutable fields. This is in contrast to Java, where making things immutable requires an extra keyword (<code>final</code>) that makes code with immutables (i.e., better, safer code) extra noisy, a great disincentive to doing the right thing. Using <code>const</code> in place of <code>var</code> in ActionScript is much prettier than the Java way. Unfortunately I quickly discovered a couple of shortcomings in ActionScript "constants" that really bummed me out.</p>

<p>The first issue I ran into very quickly: Whereas Java only allows final variables to be assigned once, it's smart enough to allow that assignment to happen in a constructor. The ActionScript compiler specifically requires them to be assigned at the point of declaration. This means you can't declare a constant field and assign it its value in a constructor, which is the primary reason I'd want constant fields.</p>

<p>Boo! But <code>const</code> was still good for static constants (obviously) and seemed to be good for locals as well.</p>

<p>The second issue has to do with using <code>const</code> on locals and led to a pretty painful debugging session. We were taking advantage of one feature ActionScript holds high over Java's head: functions are closures, and closures are handy. I was looping over some data structure using a for loop. Inside that loop I declared a const, then declared a function I wanted for later that used that const. But at the end of the loop all the functions were referring to the last item in the data structure.</p>

<p>Here's some sample code illustrating what I was seeing.</p>

<pre class="textmate-source"><span class="source source_js"><span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> Maps an array to an array of functions that return
</span><span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> the values from the original array.
</span><span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> But doesn't work!
</span><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">identityFunctions</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_js">items:Array</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>:<span class="support support_class support_class_js">Array</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
  <span class="storage storage_modifier storage_modifier_js">const</span> functions:<span class="support support_class support_class_js">Array</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="meta meta_class meta_class_instance meta_class_instance_constructor"><span class="keyword keyword_operator keyword_operator_new keyword_operator_new_js">new</span> <span class="entity entity_name entity_name_type entity_name_type_instance entity_name_type_instance_js">Array</span></span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
  <span class="keyword keyword_control keyword_control_js">for</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">var</span> i:<span class="storage storage_type storage_type_js">int</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="constant constant_numeric constant_numeric_js">0</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> i <span class="keyword keyword_operator keyword_operator_js">&lt;</span> items<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span><span class="support support_constant support_constant_js">length</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> i<span class="keyword keyword_operator keyword_operator_js">++</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="storage storage_modifier storage_modifier_js">const</span> item:<span class="keyword keyword_operator keyword_operator_js">*</span> <span class="keyword keyword_operator keyword_operator_js">=</span> items<span class="meta meta_brace meta_brace_square meta_brace_square_js">[</span>i<span class="meta meta_brace meta_brace_square meta_brace_square_js">]</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
    functions<span class="meta meta_brace meta_brace_square meta_brace_square_js">[</span>i<span class="meta meta_brace meta_brace_square meta_brace_square_js">]</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span>:<span class="keyword keyword_operator keyword_operator_js">*</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span> <span class="keyword keyword_control keyword_control_js">return</span> item<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
  <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="storage storage_modifier storage_modifier_js">const</span> funcs:<span class="support support_class support_class_js">Array</span> <span class="keyword keyword_operator keyword_operator_js">=</span> identityFunctions<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="meta meta_brace meta_brace_square meta_brace_square_js">[</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>a<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>b<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>c<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_brace meta_brace_square meta_brace_square_js">]</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
funcs<span class="meta meta_brace meta_brace_square meta_brace_square_js">[</span><span class="constant constant_numeric constant_numeric_js">2</span><span class="meta meta_brace meta_brace_square meta_brace_square_js">]</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> =&gt; "c", as desired
</span>funcs<span class="meta meta_brace meta_brace_square meta_brace_square_js">[</span><span class="constant constant_numeric constant_numeric_js">1</span><span class="meta meta_brace meta_brace_square meta_brace_square_js">]</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> =&gt; "c", but I wanted "b"
</span>funcs<span class="meta meta_brace meta_brace_square meta_brace_square_js">[</span><span class="constant constant_numeric constant_numeric_js">0</span><span class="meta meta_brace meta_brace_square meta_brace_square_js">]</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> =&gt; "c", but I wanted "a"</span></span></pre>

<p>Here's something I either never knew or at some point forgot about JavaScript: <strong>variables are lexically scoped, but only function bodies introduce new lexical scopes</strong>. So even though that <code>item</code> const is declared inside the loop, it's really scoped to the entire function. It gets assigned a new value on each pass of the loop, so yes, the <code>const</code> keyword is a bold-faced lie. Apparently the keyword tells the compiler not to let any other code assign to that reference, but it creates a mutable reference just like <code>var</code>, and in this case it gets repointed several times.</p>

<p>Basically the function definition above compiles into the same thing as this.</p>

<pre class="textmate-source"><span class="source source_js"><span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> Comes right out and tells you it doesn't work.
</span><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">identityFunctions</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_js">items:Array</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>:<span class="support support_class support_class_js">Array</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
  <span class="storage storage_modifier storage_modifier_js">const</span> functions:<span class="support support_class support_class_js">Array</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="meta meta_class meta_class_instance meta_class_instance_constructor"><span class="keyword keyword_operator keyword_operator_new keyword_operator_new_js">new</span> <span class="entity entity_name entity_name_type entity_name_type_instance entity_name_type_instance_js">Array</span></span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
  <span class="storage storage_type storage_type_js">var</span> item:<span class="keyword keyword_operator keyword_operator_js">*</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
  <span class="keyword keyword_control keyword_control_js">for</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">var</span> i:<span class="storage storage_type storage_type_js">int</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="constant constant_numeric constant_numeric_js">0</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> i <span class="keyword keyword_operator keyword_operator_js">&lt;</span> items<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span><span class="support support_constant support_constant_js">length</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> i<span class="keyword keyword_operator keyword_operator_js">++</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    item <span class="keyword keyword_operator keyword_operator_js">=</span> items<span class="meta meta_brace meta_brace_square meta_brace_square_js">[</span>i<span class="meta meta_brace meta_brace_square meta_brace_square_js">]</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
    functions<span class="meta meta_brace meta_brace_square meta_brace_square_js">[</span>i<span class="meta meta_brace meta_brace_square meta_brace_square_js">]</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span>:<span class="keyword keyword_operator keyword_operator_js">*</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span> <span class="keyword keyword_control keyword_control_js">return</span> item<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
  <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>

<p>Certainly it's my bad not knowing that the <code>for</code> loop doesn't introduce a lexical scope, but it's crazy for the compiler to allow declaration of a const inside a looping structure. If Adobe's really committed to all this static typing and compiler checking hooey, surely they'd agree this is a nasty gotcha that the compiler should prevent.</p>

<p>As far as workarounds, there are several. For the contrived example above, the simplest is to use one of the iteration methods Array has in ActionScript. There the "body" of the loop is a function, so it has its own scope. Here's the cleanest way.</p>

<pre class="textmate-source"><span class="source source_js"><span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> Actually works.
</span><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">identityFunctions</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_js">items:Array</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>:<span class="support support_class support_class_js">Array</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
  <span class="keyword keyword_control keyword_control_js">return</span> items<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>map<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span>item:<span class="keyword keyword_operator keyword_operator_js">*</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span>i:<span class="storage storage_type storage_type_js">int</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span>a:<span class="support support_class support_class_js">Array</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>:<span class="keyword keyword_operator keyword_operator_js">*</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="keyword keyword_control keyword_control_js">return</span> <span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span>:<span class="keyword keyword_operator keyword_operator_js">*</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span> <span class="keyword keyword_control keyword_control_js">return</span> item<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
  <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre><div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/23529072678094516-3048560790116607983?l=elhumidor.blogspot.com" width="1"/></div><img height="1" src="http://feeds.feedburner.com/~r/ElHumidor/~4/RVxkD-dAsq0" width="1"/></div>
    </content>
    <updated>2010-03-06T20:24:53Z</updated>
    <published>2010-03-06T20:24:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="gotchas"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="actionscript"/>
    <author>
      <name>John Hume</name>
      <email>noreply@blogger.com</email>
      <uri>http://www.blogger.com/profile/00164870439569642842</uri>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-23529072678094516</id>
      <author>
        <name>John Hume</name>
        <email>noreply@blogger.com</email>
        <uri>http://www.blogger.com/profile/00164870439569642842</uri>
      </author>
      <link href="http://elhumidor.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://elhumidor.blogspot.com/" rel="alternate" type="text/html"/>
      <link href="http://www.blogger.com/feeds/23529072678094516/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" rel="next" type="application/atom+xml"/>
      <link href="http://feeds.feedburner.com/ElHumidor" rel="self" type="application/atom+xml"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <title>El Humidor</title>
      <updated>2010-03-08T21:04:20Z</updated>
    </source>
  </entry>
</feed>
