
For a complete listing of ThoughtWorker blogs, you can go to blogs.thoughtworks.com
Last updated: 2010-03-08T19:02:00Z
Last updated: 2010-03-08T12:58:14Z
Last updated: 2010-03-07T12:36:05Z
Last updated: 2010-03-03T11:53:54Z
Last updated: 2010-03-03T11:23:47Z
Last updated: 2010-03-03T00:45:00Z
One of the arguments used to support the adoption of lean techniques in software is the success of Toyota. So do Toyota's recent quality failings undermine the case for lean software development?
One answer for this is to take a sense of proportion. Lean manufacturing techniques were the underpinning of Toyota's rise from an insignificant company in the 1950's to a global giant in the 2000's. By the 1990's other car companies, and many other manufacturers, were busily copying Toyota's techniques. The general sense is that copying these techniques did much to raise the overall quality of cars in the last decade or so. I would be very surprised if the recent problems at Toyota are enough negate that half-century of success.
But a better answer is to remember that Lean manufacturing is about manufacturing not software. The application of lean ideas to software development is a consequence of MetaphoricQuestioning. Lean ideas can help us come up with better ideas for software development, and as such are valuable. But in the end their usefulness lies with how they are used in software and they should be judged on their record here. Their history in manufacturing, both good and bad, is another industry.
Last updated: 2010-03-02T19:34:26Z
A few months back I added support for destructuring assignment and tuples to Ioke. Since Ioke’s assignment is just a regular method call, this was actually fairly easy to do. The end result is that you can do things like (x, y) = (13, 14). You can also do more interesting things, such as ((x, y), (x2, y2)) = [[1,2],[3,4]]. Notice that the right hand side is not a tuple anymore, but a list. Anything that can be turned into a tuple using the asTuple method can be on the right hand side, or an item in a recursive destructuring.
All this functionality makes code slightly more readable. But last week I decided to add support for eachCons and eachSlice, and suddenly I realized that destructuring would be very nice to have not only in the explicit assignment case, but also in cases where you want to pick apart the arguments to an enumerable or sequence method. So I added those, which means that suddenly lots of code becomes much more simple.
Short story, in all Sequence and Enumerable methods, at every place where you could put an argument name, you can now put a destructuring statement instead. Let’s take a look at an example:
Point = Origin with(asTuple: method((x, y, z))) points = [ Point with(x: 42, y: 14, z: -44), Point with(x: 20, y: 0, z: 444), Point with(x: 31, y: 646, z: 3), Point with(x: 456, y: 14, z: 12) ] distances1 = points consed map(obj, ((obj[0] x) * (obj[1] x) + (obj[0] y) * (obj[1] y) + (obj[0] z) * (obj[1] z)) sqrt) distances2 = points consed map( ((x1,y1,z1), (x2,y2,z2)), (x1*x2 + y1*y2 + z1*z2) sqrt) distances1 inspect println distances2 inspect println
This code first creates a Point that can be coerced into a tuple of x, y and z coordinates. We then create a list of Points with different coordinates. We then want to calculate the three distances between the four points. We do this in two ways, using the old method and then using destructuring. The method consed is a sequence version of eachCons. The default cons length is 2, so this will yield three entries with two points in each. We then call map on the sequence. We will get a List of two entries, where each entry is a point. Finally we use Pythagoras to calculate the distance.
The second version is very similar - the only difference is that instead of using the square brackets to index into the lists, we instead give a pattern. This pattern contains two patterns, and the variable names inside of it will be bound to the right parts of each point.
At least in my mind, the destructured syntax is much more readable than the original one. And remember, this works for anything that can be turned into a tuple, which means you can use it on any Enumerable - you can use it on a Pair (such as what a Dict will yield) or any thing you would want to add asTuple to on your own.
Last updated: 2010-03-02T12:06:26Z
So you are refreshing or rebuilding your website. You are introducing new functionality and features, and sweeping away the old. You’ve done usability testing of your new concepts and the results are positive. Success awaits. You go live. And it doesn’t quite go as you expected. You expect that the numbers and feedback will go on an upward trajectory from day one, but they don’t. What you should have expected is the dip.
In October 2009 Facebook redesigned the news feed. Users were up in arms, groups were formed and noisy negative feedback was abound. A couple of years back the BBC redesigned their newspage, “60% of commenters hated the BBC News redesign“. Resistance to change is almost always inevitable, especially if you have a vocal and loyal following, you can expect much dissent to be heard. What is interesting is what happens next. Hold your nerve and you will get over this initial dip. We’ve seen a number of projects recently where this phenomenon occurred; numbers drop and negative feedback is loudly heard. But this dip is ephemeral and to be expected. The challenge is in planning for this and setting expectations accordingly. Telling your CEO that the new design has resulted in a drop in conversion rate is going to be a painful conversation unless you have set her expectations that this is par for the course.
Going live in a beta can help avert the full impact of the dip. You can iron out issues and prepare your most loyal people for the change, inviting them to feedback prior to the go-live. Care must be taken with such an approach in the sample selection o participate in the beta. If you invite people to ‘try out our new beta’, with the ability to switch back to the existing site, you are likely to get invalid results. The ‘old’ version is always available and baling out is easy. Maybe they take a look and drop out, returning to the old because they can. Suddenly you find the conversion rates of your beta falling well below those of your main site. Alternatively use A/B testing and filter a small sample to experience the new site. That way you will get ‘real’ and representative data to make informed decisions against. Finally, don’t assume that code-complete and go-live are the end of the project. Once you are over the dip there will be changes that you can make to enhance the experience and drive greater numbers and better feedback.
Last updated: 2010-03-01T14:34:17Z
“We’ve got to have the ability to enable customers to share”
Random London Taxi driver spouting opinion on social media
“‘ere, you say you’re in IT, whatcha make of this Facebook and twitter malarky? That Stephen Fry, what a tw@t, I don’t care that he’s just woken up and brushed his teeth. Now that QI, its a fix. He’s not so bright, he doesn’t know all the answers etc etc etc…. I’ll tell ya, Facebook and all that sh!t is a bunch of arse”.
“We’ve got to have the ability to enable customers to rate and review products”
Random UK customers in a focus group
Facilitator “So if I gave you all these user reviews for the product, or a review by Martin Lewis, who are you going to go with?” Group: “Martin Lewis… yeah, I trust him, no idea who these people who write reviews are… what’s in it for them?… they are paid by the company aren’t they (cynical agreement etc)”
“Blackberrys are the business users phone”
Random teenagers in shopping centre talking about their mobile phones
“You’re nobody if you don’t have a Blackberry” (Ummmm, aren’t Blackberry’s the business person’s phone?) “You’ve got to have one coz of the Blackberry PIN for texting”
Sometimes you can get hung up in your view of the world, you make assumptions about the way the world works. Yet it can be refreshing to go out onto the street and canvas ideas and feedback. That may be as simple as striking up people on the street (people love to talk), or running focus groups for no particular research purpose other than taking the pulse of what people think. Or it may be spending time on the shop floor. Get out of the office for a day and have fun seeing your customers, consumers of your idea, in the wild. I’m not saying you take the word of a taxi driver, a comment from a single focus group or an anecdote from a shopping centre as gospel, but it might make you think and spark some new, unexpected and contrary ideas
Last updated: 2010-03-01T14:25:00Z
One of the goals that my colleagues and I urge on our clients is that of a completely automated deployment process. Automating your deployment helps reduce the frictions and delays that crop up in between getting the software "done" and getting it to realize its value. Dave Farley and Jez Humble are finishing up a book on this topic - Continuous Delivery. It builds upon many of the ideas that are commonly associated with Continuous Integration, driving more towards this ability to rapidly put software into production and get it doing something. Their section on blue-green deployment caught my eye as one of those techniques that's underused, so I thought I'd give a brief overview of it here.

One of the challenges with automating deployment is the cut-over itself, taking software from the final stage of testing to live production. You usually need to do this quickly in order to minimize downtime. The blue-green deployment approach does this by ensuring you have two production environments, as identical as possible. At any time one of them, let's say blue for the example, is live. As you prepare a new release of your software you do your final stage of testing in the green environment. Once the software is working in the green environment, you switch the router so that all incoming requests go to the green environment - the blue one is now idle.
Blue-green deployment also gives you a rapid way to rollback - if anything goes wrong you switch the router back to your blue environment. There's still the issue of dealing with missed transactions while the green environment was live, but depending on your design you may be able to feed transactions to both environments in such a way as to keep the blue environment as a backup when the green is live. Or you may be able to put the application in read-only mode before cut-over, run it for a while in read-only mode, and then switch it to read-write mode. That may be enough to flush out many outstanding issues.
The two environments need to be different but as identical as possible. In some situations they can be different pieces of hardware, or they can be different virtual machines running on the same (or different) hardware. They can also be a single operating environment partitioned into separate zones with separate IP addresses for the two slices.
An advantage of this approach is that it's the same basic mechanism as you need to get a hot-standby working. Hence this allows you to test your disaster-recovery procedure on every release. (I hope that you release more frequently than you have a disaster.)
The fundamental idea is to have two easily switchable environments to switch between, there are plenty of ways to vary the details. One project did the switch by bouncing the web server rather than working on the router. Another variation would be to use the same database, making the blue-green switches for web and domain layers.
This technique has been "out there" for ages, but I don't see it used as often as it should be. Some foggy combination of Dan North and Jez Humble came up with the name.
ThoughtWorks is a global IT consultancy. We deliver bespoke applications, no-nonsense consulting and help organisations become agile.
ThoughtWorks, ThoughtWorks Software Technologies (Xi'an) Ltd, E-101, Xi'an Softwarepark, No. 68 Keji 2nd Road
Xi'an High-tech Development Zone, Xi'an, Shaanxi, P.R. China, 710075
T +86 29 8760 7301 F +86 29 8760 7380 E info-cn@thoughtworks.com