This post has been migrated to http://www.thinkcode.se/blog/2012/09/19/want-change-and-is-willing-to-change
If you want changes and are willing to change, where should you start? When should you stop?
This is a very large subject. Books are being written on it. And it will always depend on the situation. But lets assume a few things.
- We are talking about software development
- We want our product to be awesome and profitable
Most important: Get started
The single most important thing to do is to get started. There is most likely no good reason not to get started. Waiting six months for something to change before the work is begun is just a bad excuse for avoiding a tough job.
What should you start with? It doesn’t really matter as long as the goal is to reduce the feedback loop.
Small steps and small changes are very important. Large and revolutionary changes are harder to succeed with. When they fail, they fail in more or less spectacular ways.
Always try your baby steps in a safe environment. A safe environment is any environment where a failure isn’t a big deal. It is just a failure that showed that this particular step wasn’t good in this situation.
Short feedback loop
The (almost) single most important thing is to get proper feedback as soon as possible.
A short feedback loop is essential for us to know that we are developing the right thing.
How do we shorten the feedback loop?
It can be done on many different time scales ranging from seconds when pair programming is done to hours or days when a new version is available for real customers to use.
It is obvious that if we do fewer things, we should be able get feedback on the things we actually do. Draw a value stream map and locate all value adding tasks. Remove all other things that are done before a release of the product. This will reduce the time to market and shorten the feedback loop from real users.
Add slack to the system. Never allocate tasks to anybody so they are allocated 100%. It will only result in stress, cut corners and reduced quality. You will be able to prioritize the most important thing at the moment if you aren’t allocated 100%. You will have some idle time to think and come up with better solutions than the solutions you implement today. You will have time to reflect on how you work today how it could be improved.
Tom DeMarco has written a great book on the subject: Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency
Always implement the simplest possible solution that could work, given our current understanding of the problem. Remember the words of Albert Einstein “Everything should be made as simple as possible, but no simpler.”
The real test for a piece of software is when real customers use it in their normal environment. This is when we can get feedback of what is good and what is bad for these specific users. The users can only give us feedback after they have had a chance to use our product. They will only be able to react on changes if we release frequent.
The implication of this is that you must strive for continuous deployment. You may not get there, but releasing every few days or every few hours is probably close enough.
Automate the releases
Releasing a piece of software is about placing the correct files on a proper server. A server process may need to be started. These are tasks that are easy to automate. The problems that will pop up are commonly related to territory and job description issues. These non-technical issues have to be resolved, but that is often more of a negotiating task than anything else. Somebody with enough power must decide that fast feedback from real customers are important and remove these obstacles.
Change how the work is done
The way the work is done today is not good enough. A change must be implemented.
It is important to realize that the flow through the development system is a lot more important than optimizing a specific resource. If we don’t give flow priority, then will we create unnecessary queues and stretch the feed back loop instead of tighten it.
Empower the development team so they are allowed and able to take their own decisions. Trust people to do their job. Most individuals want to do a good job.
Create cross-functional teams of specialists. All competences should be available in a cross-functional team so all decisions can be taken directly.
Prefer direct communication instead of written communication. It is a lot easier to verify that the message has been received as the sender meant it when both the sender and receiver can ask questions.
Communicating using issue tracking systems may be one of the worst possible ways to communicate. Especially if the parties that need to communicate are co-located.
Raise the competence level
Everyone involved with the development must be as good as possible at his or her work. This means constantly raising the competence level.
Education may seem expensive, but it is even more expensive not to educate your programmers so they can move from good to great.
Demanding the developers to use a specific way of working is not enough. You will probably have to teach them and actively raise the competence level within the team. If developers don’t know how to develop code with TDD, make sure they learn how to do it.
Using good tools that solves the problem is given. Allow the developers to select their own tools. Avoid forcing a tool set on the developers. There must be some common tools for a product. The build tool is one example. I would suggest using Maven for Java products. The version control system is another example. I would suggest using Git whenever possible. Git has been selected as the version control system least in the way during daily work among the developers at Thoughtworks.
There are many good practices within software development with the common goal to keep a short feedback cycle.
Pair programming: two developers, one computer and one problem. The feedback cycle is instant; two people that are talking can give feedback very fast. It may seem wasteful to have two people punching the keyboard, but if you think that then you have never worked as a programmer. Typing has never been the bottleneck. The bottleneck is the problem solving part. Solving problems in a group is something people have done as long as we have been able to communicate. Why should this stop just because we are sitting in front of a computer?
Test driven development, TDD: Write a test for a small piece of functionality before you implement the actual production code. The idea is very simple and the feedback very fast. Normally the feedback is received within seconds after writing a piece of code. An additional benefit is the fact the system gets thoroughly tested and any future changes will be easy to add knowing that none of the existing functionality is broken.
Behavior driven development, BDD: Define the expected behavior for the system before your write any code. BDD is similar to TDD but on a larger scale. There are more similarities between TDD and BDD than there are differences. BDD is often slower compared to TDD. The main reason is often that you verify larger parts of the system. Setup and execution is slower. The feedback may never the less be received within minutes from writing a piece of code.
Automated testing doesn’t stop at the lowest level. It will continue at higher and higher abstraction levels.
Continuous integration, CI: The practice of compiling and testing the system. A CI system will typically be able to deliver feedback in minutes after committing new code to the version control system.
Continuous deployment, CD: Deploy the product when the build and all checks have passed. This will enable the feedback from real customers. The feedback is possible to receive within hours after a new feature has been released.
To get good programmers we need educated people that are interested in problem solving. Then we teach them to use baby steps, drive their code using good tests and never accept that things cannot be improved. Accepting things as they are is not an option. The people we need and want will always strive to improve their surrounding environment.
This always means that there is a need to raise the competence level for the developers. It also means that there is almost always a need to change the ways of working. Valid tests must be defined and implemented so they can be executed automatically.
It is important to understand and accept that developing software is a team and people activity. See your co-workers as human beings and not resources. A resource can be replaced, a skilled co-worker is not easy to replace. It is not like replacing a tire on a car.
Keep challenging your co-workers to think better, do better and ultimately perform better. That way they are not tempted to leave the company.
When everything above has been implemented and we have a very short time period from idea to production, is everything perfect then? The answer is no. Perfection is not a place; it is a direction. No matter how good we are, we can always be better.
Close the feedback loop as much as possible. This will give you information about what else to fix with your product.
Feedback from real users within hours from releasing a new feature is priceless. Remember, real feedback is only possible if real users can use the product.
Never stop improving. It is always possible to do a small change and see if it has any effect on the performance.
In short: Better software through faster feedback.
This post has been reviewed by some people who I wish to thank for their help
- Malin Ekholm
- Johan Helmfrid
Thank you very much for your feedback!