I recently read 2 second Lean by Paul Akers. It’s a marvellous little book. It has re-ignited my deep-seated love for lean thinking, and in particular for continuous improvement via aggregation of marginal gains. I highly recommend you take the 2-3 hours to read it, and then look for ways to apply Akers’ ideas to your team.
Partly inspired by 2-second Lean, and partly by the mob programming practice of daily retrospectives, I’ve recently been experimenting with using daily retrospectives for continuous improvement. Imagine you ran a retrospective at the end of each day, using only the following question:
Let’s set aside the first 30 minutes of tomorrow to eliminate, forever, some of the waste we saw in our practices today. Let’s see if everyone in the team can remove at least 2 seconds of time we wasted today not delivering value. Which 2 seconds should we choose to eliminate? And what shall we do to achieve that?
What would you pick? Ideas from the teams I work with have included learning keyboard shortcuts, using Sublime Text instead of Visual Studio, deleting unused code, documenting setup steps in a wiki, and so on.
Perhaps you could also follow Paul Akers’ practice of making “before” and “after” videos of your improvement, to share with other teams? (Hopefully I’ll find the time to share some of my personal 2-second kaizen videos here soon.)
In Fundamentals of Object-Oriented Design in UML Meilir Page-Jones offers the following guidelines for system maintainability:
- Minimise overall connascence
By breaking the system into encapsulated elements
- Minimise connascence crossing encapsulation boundaries
By maximising the connascence within encapsulation boundaries
This feels like something of an “algorithm” for refactoring, if only we could quantify what “maximise” and “minimise” mean. In the next few months I’m going to have a stab at doing just that, with the help of audiences around Europe as I roll out my new talk “Love and Death: Everything you always wanted to know about coupling but were afraid to ask”. I plan to report back here as the wisdom of crowds helps me flesh out what the above algorithm might mean. First up is XProLo next week, followed by NWRUG in July. Watch this space…!
Last week Andy Longshaw and I ran our “Agile: It’s not just about the development team” workshop again, this time at XP2016. You can read Andy’s report, and see the posters created by the participants, here. This time we had 90 minutes, which felt a lot less rushed than the 60 minutes we had at AgileManchester last year (read Andy’s report of that run here).
Workshop in progress
We have run this workshop four times now, twice at conferences and twice as in-house training. Each time generates great discussion around how the non-software parts of the business need to change their strategies in order to support, cope with and capitalise on a highly agile development team.
Write commit messages so that:
- they complete the sentence “This commit will…”
- the commit log can be understood by your Product Owner
- they describe the “why” — because the “what” can be read in the diff
Make the sign-up button look like all other calls to action
Ensure the timezone is always correct on UAT
Allow clients to retrieve the time when an application is rejected
Import the new LESS file on the home page
Updated endpoint for rejected
I have a side project that I use as a sounding board to help me learn about “modern stuff”. The front end is built with React + Flux, and the back end persists information via event sourcing instead of a SQL or document database. I’m enjoying the experience of working with these tools, and so far everything has gone smoothly. But now I have a puzzle, which I will share here in the hope that one of you can point me in a good direction.
This month James Jeffries and I ran a session at Agile Manchester in which we (ie. Jim) live-coded Dave Thomas‘s Back to the Checkout kata. The twist was that during TDD’s “refactor” step we used only connascence to decide what to change.
(I know I’ve done that before, on this blog. But this time Jim and I started with different tests. And we practiced a bit first. So the resulting refactoring steps are quite different than those I wrote about earlier.)
@ruby_gem kindly pointed her laptop at the screen and recorded the session. (The beauty of this setup is that you get to see what Jim types and hear how we explain it, but you don’t have to suffer from seeing either of us.)
The slides we used are on slideshare, and I’ve uploaded the resulting video to youtube for you to view at your leisure. Comments welcome, as always.
I just had a thought about the relationship between software development and the Theory of Constraints. It probably isn’t a new thought, although it seems to differ from some of the analyses I’ve seen elsewhere. Also, I probably won’t be able to express it in any coherent way; but here goes…
Recently I wrote a series of posts in which I attempted to drive a TDD episode purely from the point of view of connascence. But as I now read over the articles again, it strikes me that I made some automatic choices. I explicitly called out my design choices in some places, while elsewhere I silently used experience to choose the next step. So here, I want to take another look at the very first step I took.
Am I over-thinking things with this Checkout TDD example? Or is there a real problem here?
Based on insightful input from Pawel and Ross, it is clear to me (now) that there is CoA between the currentBalance() method and the special offer object(s), because the method doesn’t give those objects any opportunity to make final adjustments to the amount of discount they are prepared to offer.
However, as things stand there is no requirement demanding that. Does that still mean the connascence exists? Or is it a tree falling in the forest, with no tests around to hear it?
I had a very interesting discussion today with Ross about my recent connascence/TDD posts. Neither of us was happy about either of the solutions to the corruption problem with the special offer object. Even with the cloning approach, it still seems that both the Checkout and the MultiBuyDiscount have to collude in avoiding the issue; if either gets it wrong, the tests will probably fail.
After a few minutes, we realised that the root of the problem arises from the MultiBuyDiscount having state, and we began to cast around for alternatives. At some point it dawned on me that the origins of the problem go right back to the first article and the first couple of refactorings I did.