March 17, 2015 § 1 Comment
I have to acknowledge a blunter truth about my relationship with TDD. That is to say I don’t do much TDD because a) I’m impatient, and b) I like to code impulsively. I strive to have the problem space booted up in my head and then walk around it arbitrarily, as Paul Graham has written about in his ‘the head’ article. When solving a problem I may start out with a vague idea of how the design will play out, but really I just want to try out a few rapid ideas, weighing up the various pros and cons as I go. I may use some tests, I may not.
My thinking is that TDD – as applied by the masses – compromises one’s ability to code intuitively against the problem space in their head. By formally marshalling the art of coding into a series of strict red/green chequerboard moves, your overall ability to think laterally about the problem is reduced.
At this point I must readily concede that the TDD conversation can’t be had without considering the technologies and languages involved. If you are doing battle with a traditionally large OO code-base, then TDD may be appropriate for a host of reasons. Primarily, it does keep you on the rails.
Being honest, can we admit that hacking on large OO systems can be a huge amount of fun? You get to lose yourself in a giant Sudoku. Design patterns, generics, some magical AOP code, what’s not to like if solving complex problems is your thing? The trick for many is to not to get lured in, however tedious that may be.
I do therefore hold respect for TDD in certain contexts. It’s like a puritanical response against the will of developers to get stuck into battles that we should probably be avoiding. TDD helps to keeps the mind clear, to keep it focused. There’s a world of dark and dangerous refactorings we could be doing if we let our inner impulses off the leash. Beginners may find TDD a useful tool to take incremental steps, and this indeed is a strong point in its favour, as discipline aids learning.
I just think that if you need TDD all the time to engage with a code-base, then it’s a smell of something being overly complex.
There is then the other the argument that TDD’d unit-tests are really just the same thing as REPL sessions, so therefore it’s unfair to attack them, that they are really just fulfilling the role of the safely walled-in playground. My view is that it sure doesn’t feel this way when I’m wrestling mock frameworks and spending hours of my life wiring stuff up, unless the playground is of the variety found in the Terminator 2 opening sequence. There’s a reason BeanShell sadly didn’t get widespread traction; you need a simpler language to make the REPL a pleasant experience.
My main overarching concern isn’t just the intuitive development approach though, as that’s largely horses for courses and is subjective to the individual. My main worry is about aesthetics, and the reason I’m pondering this is because Eleanor McHugh brought it up on a recent panel debated on TDD prompted by DHH’s article on “TDD is dead. Long live testing”.
It’s surely a worthy goal for code to be beautiful, to be aesthetically pleasing to the eye. Given developers will be spending years at a time patrolling a single code-base, it pays to have the code elegant and prideful looking. Beauty in code has a high correlation with simplicity, and it’s usually evident when a developer has thoroughly understood the complexities of the problem and has pinned down the right level of abstraction.
When a codebase has been dogmatically TDD’d, I think it ends up looking a little sad, as though the chunks of production code are being unfairly surrounded by unit-test SWAT teams. Everything is in a state of lock down, where you are restrained against making serious changes because the effort required to work with someone else’s tests is just too high. You then also have to suffer the moral quandary of considering whether to delete someone else’s test code, this isn’t trivial and so useless code has a habit of sticking around.
I don’t believe rigid TDD as applied by the masses is a good thing for aesthetics in code. I think it’s rather the opposite case, as going-through-the-motions unit-tests tend to take on opposing aesthetics. Through the eyes of a TDDist, one sees beauty in ensuring that every edge case is accounted for, and that every discreet piece of logic has a test. A TDD’d codebase can therefore be a sterile place. Well tested and functional, just lacking that human touch of grace and simplicity.
October 24, 2012 § 2 Comments
My last post covered the rationale behind our team at an investment bank wanting to make a switch to Clojure from Java. I want to write in this post about how we were supported in our efforts by those at the bank.
Aircover from Within
First not all the team jumped in at once to use Clojure. We created what we called a ‘pod’ within our team. Invitation to the pod was extended to all but to join you had to get the Emacs/Swank/Lein environment setup working first by reading our projects github README page. People joined the pod at varying times with their own personal approach. I.e. some devs wanted some space to try out their own thing in the Clojure codebase whilst others wanted to pair up. Some devs wanted to install the very latest version of Emacs themselves and understand all of our Emacs config whilst others took a more direct route through to the code. At one point we had an Emacs versioning arms race of which I dropped out.
Some of the team didn’t join the pod initially and stayed back to provide air-cover to those within the pod. For the system we had to maintain/develop they stepped up to satisfy whatever business requirements came our way as well as handling any emergent technical problems. Gratitude is owed and deserved.
Technical Leadership Vs Bottom Up, Organic Adoption
I’ve heard of a case at a different investment bank of someone fairly senior decreeing that development going forward needs to be done using Clojure (I disclose now that I don’t have all the facts). I’m not sure how I feel about the idea of this. On the one had it feels good that someone high up has got a kick-ass mentality to drag up the quality of the tools that people in the trenches are using to eliminate waste and to speed up development. On the other hand I can see some people getting frustrated – i.e. not everyone wants to get bloody on the cutting edge and to call themselves Lisp hackers, having to revert from the cosy wizardry of professional refactoring powerhouse tools like Eclipse/Intellji to having to use Emacs or Vim, tools of old.
Changing from a statically typed OO language to a dynamically typed FP one is a fundamental change requiring lots of organic support and I’d be interested to hear if it can be forced or not. Maybe it can be. Maybe this is good. There’s also still immaturity around the Clojure tools ecosystem to grapple with. Nrepl is replacing Swank-Clojure, Lein 2 is about to be released which is a major upgrade. Although you can get copious amounts done using Clojure one has to say that the ground still has the occasional tremor and this may affect bringing onboard the masses. I would expect that there is lots of devil in the detail around Clojure mass adoption.
At our bank we were given some room and trust to take technical decisions so long as our cost/benefit case was solid. It felt right for our team at the time to start using Clojure – we were not instructed to do so.
Support from the Business
The Business were typically not as patiently supportive as our technical stakeholders. However pleasant our business customers are there’s always an element of ‘why we have got X amount of the team diverted away from serving the direct requirements of the business to do tech stuff?’
It may sound obvious but the only effective way I’ve found to deal with this is get a synergy between the ‘tech stuff’ and needs of the business as soon as is reasonable. Our pod of Clojure devs made a switch from straightforward 100% reengineering to doing a mixed blend of new requirements for the business too. Now the business are happier and we get some relief. Since development is more productive around our new infrastructure we can turn around long standing requirements for them faster and it’s fun to do. They will reap the rewards from here on in.
This does however mean that we’ve increased the amount of work we’ve signed up for and overall pressure on ourselves, this has affected our morale. We are currently sailing quite close to the wind with anti-patterns ‘scope creep’ and even at times ‘death march’ hovering. There’s no doubt that we’ve had our share of stresses and that there are more to come. I can though take some comfort that with hindsight the thought of sticking with the old status quo of a monolithic Java app does not become any more appealing. Eventually the waste will crush no matter what the resources of an institution.
July 28, 2009 § Leave a Comment
This is a post about the practice of risk management through use of a ‘DEFCON Door’.
A DEFCON door? Well if you’ve seen that early 80’s film ‘WarGames’ starring Matthew Broderick, or if you simply know your US history, then you’d know that DEFCONs – Defense Readiness Conditions – are used to be a “measure of the activation and readiness level of the US armed forces” (as described on wikipedia). During the Cuban missile crisis DEFCON 2 was reached, with the US airforce readied up to go and bomb their cold-war rival the USSR.
And how might this be applicable to your typical day-to-day IT project? For starters, once on a project what we did was to find a spare door and to configure it as such:
It’s very simple really. Along the top column headers are the various DEFCONs. DEFCON 1 would mean that it is the consensus of the team that the project is going to fail because of a particular issue; that a very serious risk has indeed materialized. DEFCON 2 risks are still very serious, and DEFCON 3 ones are merely lesser risks that the team feel are important enough to warrant exposure at a particular given time.
What I found most pleasing about the DEFCON door was that it seemed to be a fairly natural extension of the Agile software development practice and was therefore well-adopted by individuals on the project. For instance in a similar way to how we do story estimation a person would read out a ‘risk card’ and then the team would count to three and display with a finger count the the DECON level that they thought the risk had reached. No fingers at all meant that the risk could simply drop off the door altogether – which ought to be a good thing.
Normally every couple of days or so after the standup we would do a quick review of the door. Sometimes, we also did it after a retrospective, because a few things that had been brought up were indeed risks that the team thought were ‘DEFCON appropriate’.
Risks would sometimes traverse up and down through the DEFCONs as the team would attempt to grapple with them, and often risks would be broken up into multiple risks, or instead merged together to form all encompassing ones. No one team member should own the door as it works very well as a collaborative tool where everyone can have input.
Thoughts on effectiveness:
I think often individuals within a team will have very real concerns about some particulars of a project. Personally speaking, one of the wants that I have when I have such concerns is that my concerns will be listened to and registered by the team, and I think the DEFCON door to an extent gives you that.
It also brings the team closer to the risk tracking that would ordinarily be done by project-managers. Although I don’t think it should be a replacement as it best works as a lightweight tool, there’s real value in having team-members contributing to tackling and identifying risks on a day-in, day-out basis.
The DEFCON door also has uses outside the immediate vicinity of the team, such as the ability to show project stakeholders the door and say “these are the major risks that the team feels are present right now”. Often stakeholders not operating within the team will have a want to gauge a collective opinion about how the project is going and the challenges that are being faced. Here the door can play a useful role.
Firstly, it sometimes can be difficult to locate a usable door, especially a nice wooden one. If need be you could use a wall, but then you’d be harming the linguistically pleasing flow of the “DEFCON Door”. It is however, really up to you.
Understanding what the scope is of the door can be at times slightly difficult. For example it can be tempting at times to throw up enterprise-wise risks up on the door that are not directly project-related (e.g. is this architecture appropriate for adoption by the wider organization?). A strategy a colleague of mine came up with is to have a DEFCON corridor, but I fear this may be over-egging the solution. I would endeavor to keep the door simplistic, and if the door identifies risks and questions to be managed elsewhere then that can only be a good thing.
We should also note that this model of risk management is very lightweight and simple, and that there is much more about risks than can easily tracked and measured on the door. Therefore it would seem appropriate to use it to augment a more sophisticated risk management process.
In conclusion, the DEFCON door is a simple tool that aims to bring risks explicitly into the highly visible and participatory realm of an empowered, self-organising Agile team.