This is the first post in a series of posts about anti-patterns that I have seen in my travels. I thought it is helpful for people to understand what is common in projects that fail so that they can learn from others’ mistakes and failures. Over time I will post more and more patterns and I will also post signs of success in a parallel series of blog posts. While these posts are numbered, they will not strictly be in priority order and will rather follow the same pattern as my other posts, which are timely to discussions I have had close to the point of writing the post. Perhaps later I prioritise them, but for now let’s get them on paper.
The number 1 reason I see in teams that fail is that they don’t have effective retrospectives. This can have many reasons, but the most common one I see is that the team does not have time because delivery is taking all their time. They are already working overtime and now they are asked to spend an hour on a retrospective. Clearly that can wait until next iteration. You might ask: how the next iteration will get any better if there is no time to look at what went wrong this time and to improve it. And you are correct. It is likely that the next iteration will end up consuming all the time and there again wont be time for a retro. In my opinion it is not often the case that there is really no time, it’s just a lack of understanding of the importance of the retro and perhaps the experience that previous retro wasn’t effective. One sure way to get teams out of the habit of running retros is when there is no action out of the retro, the team is bringing up all kinds of challenges they had and everyone is happy to pitch in and perhaps actions are also discussed on how to improve things, but then nothing happens. Sometimes the iteration is already committed and there is no room to action anything above and beyond the committed scope. Sometimes the ScrumMaster is not willing to pursue organisational challenges that require escalation and rather waits it out. Sometimes it is simply that no owner was assigned. Whatever it is, if after a couple of retros the team is still highlighting the same challenges and nothing is being done about it, they will question the value and then find it harder and harder to find the time to even do a retro. So perhaps it is not a time problem after all.
I personally like this cartoon, which pretty much sums it all up:
So how do you avoid this sure way to fail:
Hold regular retrospective – The first remedy is to hold retrospectives regularly and to make sure the team participates. One thing I learned is that there is not one format that works for everyone. You will have to experiment with the team until you find the right duration and activity to get maximum participation. And over time you should mix it up. To put post-it notes under two columns for good and bad can get pretty boring and take away from the value that the retrospectives add to the team.
Follow-up with action – The best retrospective does not help if it is just a session for feedback and then people leave and the system cards and ideas remain in the room. You need to make sure that at least 1-2 actions are taken from each retrospective session and that these actions are visible to the team (ideally on their Kanban wall). If you are the Scrum Master and there have been actions for the organisation that have come up in the retrospective and that the team thinks are important, then you need to make sure that you are accountable for doing something with it. I have attended retrospectives with teams over time and the motivation of the team is proportional to the level of action that comes out of a retrospective.
Bubble up what needs to bubble up – While many actions from the retrospective are internal to the team, there are items that are of interest to the whole organisation and where teams can learn from each other. One risk of the very team focuses ceremonies of Agile is that teams learn but not the organisation. It is therefore that the team and the Scrum Master and any coaches involved make sure that insights from retrospectives are being bubbled up to the organisational level to allow for that exchange of lessons learned and that actions can be taken for things that impact many different teams.
License: Creative Commons
by Paul Downey from https://www.flickr.com/photos/psd/
License: Creative Commons
Okay so training was more work than expected, hence I will now slowly make my way through the backlog of topics. We will start with some the different techniques being used in DevOps. I will move the definitions to my definitions page as well, as I will refer to them again and again over time I am sure.
Continuous Integration (the practice)
This is probably the most widely known in this list of practices. It is about compiling/building/packaging your software on a continuous basis. With every check-in a system triggers the compilation process, runs the unit test, runs any static analysis tools you use and any other quality related checks that you can automate. I would also add the automated deployment into one environment so that you know that the system can be deployed. It usually means that you have all code merged into the mainline or trunk before triggering this process off. Working from the mainline can be challenging and often concepts like feature toggles are being used to enable the differentiation between features that are ready for consumption and features that are still in progress. This leads to variants where you run continuous integration on specific code branches only, which is not ideal, but better than not having continuous integration at all.
Continuous Integration (the principle)
I like to talk about Continuous Integration in a broader sense that aims at integrating the whole system/solution as often and as early as possible. To me Continuous Integration means that I want to integrate my whole system, while I could have a Continuous Integration server running on individual modules of the system. This also means I want to run integration tests early on and deploy my system into an environment. It also means “integrating” test data early with system to test as close as possible to the final integration. Really to me it means test as far left as possible and don’t leave integration until Integration Test at the end of the delivery life-cycle.
Continuous Delivery vs. Continuous Deployment
What could be more confusing than having do different practices that are called CD: Continuous Delivery and Continuous Deployment? What is the difference between CD and CD. Have a look at the summary picture:
As you can see the main practices are the same and the difference is mainly in where to apply them. In Continuous Delivery you aim to have the full SDLC automated up until the last environment before production, so that you are ready at any time to deploy automatically to production. In Continuous Deployment you go one step further, you actually automatically deploy to production. The difference is really just whether or not there is an automatic or manual trigger. Of course this kind of practice requires really good tooling across the whole delivery supply chain: everything that was already mentioned under continuous integration, but you will have to have more sophisticated test tooling that allows you to test all the different aspects of the system (performance, operational readiness, etc.). And to be honest I think there will often be cases where you require some human inspection for usability or other non-automatable aspects, but the goal is to minimise this as much as possible.
Last but not least Continuous Testing. To me this means that during the delivery of a system you keep running test batteries. You don’t wait until later phases of delivery to execute testing but rather you keep running tests on the latest software build and hence you have real-time status of the quality of your software and if you use Test-Driven-Development you have real-time status of progress. This is not terribly different to the others mentioned before but I like the term because it reflects the diffusion of testing from a distinct phase to an ongoing, continuous activity.
I hope this post was helpful for those of you who were a bit confused with the terms. Reach out with your thoughts.
This week you will see more content than the usual once per week posting. I am training technology architecture and as such I will include a daily post as basis for discussions in the course. Post the discussion in class I will update the post with a summary of the discussion. I hope you find this an interesting concept as I am experimenting with the blog medium. On to the first topic of four: Technical Debt.
Much has been said about technical debt and how hard it is to pay it down. In the last week I had a few discussions about this and I thought I put my thoughts down on paper (or really the keyboard).
What is technical debt?
To get everyone on the same page let’s define what technical debt actually means. Technical debt is best explained by what it causes. Similar to debt, it causes interest over time. And as you all know interest is basically paying money for which you don’t really get anything in return. You are paying for an earlier decision (e.g. a purchase you made when you could not yet afford it) and if you don’t start paying down the debt then you will be able to afford less and less with the same amount of money as the interest takes over.
In IT what happens is that you set out to implement a new solution and of course you try to deliver the best solution possible. Over time decision points come up where you could implement something that costs a bit more but would provide better maintainability later on, like automated unit testing or separating out a function that you might reuse later rather than keeping it within a different function. You now need to decide whether to invest the extra time/money for this non functional aspect or to focus purely on the functionality that your business stakeholder requires. Every time you choose the short-term solution you increase your technical debt as next time you want to change something or use the functionality that you could have split out, you now require an additional effort. Of course there are many more ways to incur technical debt than just the lack of automation or modularisation, but these serve as examples.
Why is it so hard to avoid technical debt?
The crux of the matter is that by making all the right decisions (according to some criteria), you can still incur an increasing amount of technical debt. Imagine you are working on an application and you have exactly one project and you don’t know whether there will be any other projects after you. Should you still make the investment in good automation and modularisation practices? What if you know there are other projects, but you don’t know whether it will impact the same areas of the code or would use the same automation? …
You can see its a slippery slope.
Look at the graph on the left. It shows the total cost of change over time, initially it is cheaper to just implement the functionality without investing in good practices, but then over time the cost of changes increases as the technical debt makes it more costly to make changes. At some stage the total cost of change means each change is now more expensive than if you had implemented all the good practices from the beginning, but now you have to pay down all that debt and it is costly to jump back to the other cost line. You also see that even with great practices the cost of change generally increases a bit over time, although there are people arguing that great modularisation and reuse can actually reduce the total cost of change over time as you recombine existing services to create new ones, but that is for another post.
What does it take to pay it down?
The challenge with paying down technical debt is that it usually takes a lot of time and while you can accelerate it through a dedicated program, the only long-term solution is to leave the software in a better state every time you make a change. Otherwise you run a “paydown” project to reduce technical debt but then increase it with each subsequent functional project until you do the next “paydown” project. If you do it little by little you will have a much more sustainable model and the cultural shift that is required to do this will be beneficial for your organisation in any case. If your Agile implementation can help by making the technical debt more visible and by visually tracking each time you pay a bit of debt down, then you are onto a model that get you to the total cost of change curve that you aspire to. And my personal view is that you need to make sure that the PMO organisation and the project managers are clear about their responsibility in all this. They should be evaluated not only by the on-time and on-budget delivery of functionality but also by how much they have done with their projects to pay down technical debt, otherwise PMs are too often likely to choose the short-term answer to achieve on-time, on-budget delivery at the cost of technical debt for the next project or in not so kind terms by “kicking the can a bit down the road”.
How can you measure it?
Here I am still without a really good answer…theoretically I think it is the sum of the additional cost that each change costs at the moment minus what it would have costed if you had all the good practices in place. But that is really hard to calculate. Alternatives that i have seen are to create a backlog of all the things that you should have done and to add to it every time you make a short-term decision. The size of this backlog is you technical debt in this case. Not yet great answers, but i keep looking. Please reach out if you know of a better way.
Picture: 3D Shackled Debt by Chris Potter from http://www.stockmonkeys.com
License: Creative Commons
I felt compelled after some recent discussions to provide another blog post about the analogy I have been using in the title of this blog: The Software Delivery Factory model.
Let’s talk about the traditional way of thinking about Factories:
We start from the Wikipedia definition of factory system characteristics
- Unskilled Labor – Now while labor arbitrage has certainly been a factor in the move towards a software factory model, I think we all agree that we are unlikely able to move away from at least a mix of experience levels and that we cannot sustain good software delivery without the right skills. In this model people are usually referred to as resources, but that’s for another post later. Inappropriate analogy!
- Economies of Scale – By bringing together everyone involved in the delivery process and by centralising some of the functions like PMO we do see some economies of scale. Appropriate analogy!
- Location – In the past this has been about factories being close to infrastructure like rivers, roads and railways, these days it is to be close to the right talent. This continues to be important as you can see in the move to India and China to get closer to large talent pools there, and also in Silicon valley where a lot of top talent is located these days. Appropriate analogy!
- Centralisation – In a factory means for production were brought together which individuals were not able to afford (e.g. an assembly line or weaving machine). In software delivery we see heaps of small competitors taking on the big guys with sometimes more advanced open source technology. We also see a lot of distributed teams across the globe who work from different office or even home. Inappropriate analogy!
- Standardisation and Uniformity – How often do we produce the same piece of software many times over. Not really that often. There are some cases where the same pattern is required for example for pricing changes, but more often than not each project requires a unique solution and is contextual to the client and technology used. Inappropriate analogy!
- Guarantee of Supply – In a factory the work flows relatively smoothly and there are few hiccups if any in the production process. Looking at data from the chaos report and looking at my own experience, the smoothness of flow in software delivery is an illusion. And to be honest if I see a burnup or burndown graph that is smooth I suspect some gaming is going on. Inappropriate analogy!
So in summary the vote goes to it not being an appropriate analogy 4:2. It conjures up images of people sitting in their cubicles actioning work packages,
- one person translating a requirement into a design handing it over to
- the next person writing a bit of code
- then to the next one testing it
- and in all this no one talks to each other, it’s all done mechanical like people on an assembly line
In bad times software delivery in a factory model can feel a bit like Charlie Chaplin in Modern Times
Some of my colleagues talked to me about a new factory model, so let’s talk about the characteristics of this alternative model that people point out to me:
- Orchestration of complex production process – software delivery today does require the delivery of many individual components very similar to the complex production process that for example is required to build a Boeing Dreamliner. Most systems are built of many components who are developed by many different team sometimes even across many locations and organisations thanks to the offshoring and outsourcing models. This examples of a modern factory does apply to software delivery. Appropriate analogy!
- Automated Tool chains – If you look at modern factories from Toyota or BMW, you see very few works and a lot of automaton chains. This is very similar to this little video on CD. In that regard I agree that software delivery should be like these modern factories. Appropriate analogy!
I guess a modern BMW factory is the right analogy for this model:
Overall we end up with 4:4 votes on this list. In my head the image of a factory is not that of empowerment and of people working together to achieve great unique outcomes, its one of mass production and that just doesn’t work well with my understanding of software delivery. I guess I will keep the name of my blog as it is and just look forward to many more interesting discussions about this topic.
Here are some thoughts from others on Software Delivery Factory models (and yes of course it is more likely I come across things that confirm rather than oppose my view – please call out references to opposing views and I will post them here):
Those of you, who have shared a meal, German beer or single malt with me, know that I am passionate about psychology (especially social psychology and cognitive bias). Given how often this relates to my work and the topics in this blog, I think it is time to do my first post about psychology. It’s about the Abilene Paradox (a shout out is required here to the social psychology coursera course from Scott Plous – where I learned about it).
What is the Abilene Paradox?
The Abilene Paradox is when a group reaches consensus to do something that nobody in the group actually wants to do. Everyone ends up doing something they think everyone else wanted, but nobody did. Let me explain this with an example from my personal life and you can read the original name-giving example here. So let’s see whether you can relate to this:
You had a pretty busy week and on your way home on friday you think: “This week I hadn’t had much time for my wife, so I will make an effort and we go out together even though I rather stay at home on the couch and watch TV together”. You walk in the door and say: “Honey, what do you wanna do tonight”. She responds: “You must be tired, so perhaps we stay in. It’s OK you know” and internally she thinks: “I had a rough week as well, so we should stay home and have some quiet time”. You then respond to her: “We could go out for dinner?” and to be nice she responds “Ok, that sounds good”. You both head out for dinner and sit in the restaurant and after an average meal on the way home she says to you: “Honey, i wish we would have just stayed home.” You look at her and even though you both agreed on what to do, you ended up doing what neither of you wanted to do in the first place. Now does this sound familiar to any of you?
Example from work
How does this relate to work you might ask. Quite often when looking for solutions people don’t put forward the solution they think is best but rather a solution they either think others expect or (and I have been guilty of this as well) an idea they think is “out-there” just to find out what the reaction is. Now imagine everyone else in the room thinks the same way or just doesn’t want to disagree…all of a sudden you are on your way to Abilene.
It gets worse when you are in an environment where there is a bit of distrust. Imagine you think your boss wants you to run a certain project that you think is doomed. You provide status that is not a lie, but in the grey area to make it look okay and sound upbeat about it because you think your boss wants it. Now he might encourage you to continue working on it even though he has his doubts. Neither of you call it out and you spend days, weeks, months on something neither of you think can be successful.
What to do about it
First of all speak up. It is really hard to get out of this kind of group dynamic if there is no-one who has the courage to speak up. I have heard the expression: “Going to the balcony” in this context and it always reminds of the old Waldorf and Statler from the Muppets. It means look at the situation mentally from a few feet away. More than once in my life have I said: “Guys, let’s take a step back. Is this really what we want to do? Who here really thinks this is the best option?” In the past I always wondered what happened to us, now I know we were on our way to Abilene…
There are many ways to try to avoid this, and a lot will depend on the context. You can try a secret vote to find out the real deal, you can ask someone to actively propose an opposing view or you can use fist to five and look out for 3s (if the majority has a 3, you might want to dig a bit deeper).
I hope you enjoyed this first trip into psychology on my blog, there will be more to come. Stay tuned until next week.
Picture: Why doesn’t anyone read the signs? by Neil R
taken from https://www.flickr.com/photos/islespunkfan/
under Creative Commons license