- Rushing makes us neither faster, nor more productive; it increases stress and distracts focus. We need creativity, effectiveness, and focus.
- Hire better talents, do together, practice together and learn together to improve professionalism and cultivate craftsmanship in your organization.
- Improve adaptation of your team and efficiency of your processes by doing plans & revising them often, collecting & analyzing and eliminating waste.
- Without having a quality codebase, you cannot be agile. Push defects down, release frequently, test first and refactor and focus on simple design.
- Working software doesn’t have to be well-crafted. Only good professionals can build well-crafted software, and only well-crafted software lets you build faster than ever.
Going fast without control could be the biggest enemy of software development. The three main areas where you should slow down in are people, process, and product. Before digging into details, let me start with a story.
I guess it was 2011. I joined a team responsible for building an online marketing platform. My main responsibility was adding new features to the system as fast as I could. Hey, I was the senior developer. We call developers “senior” when they are able to develop faster than others, right? However when I joined, we noticed that it was almost impossible to go fast due to technical debt and design challenges. At every single attempt to go faster, we noticed that we increased the complexity and destroyed the quality. It seemed to me that the only way to gear up was to rewrite the whole system from scratch.
I remember, I called the product manager and said we needed to rewrite the whole system. After 30 seconds of silence at phone, the project manager answered, “you are saying that your team wrote your product so poor quality that the same team has to rewrite the same product again, but better this time. Right? Sorry man, it is unacceptable. You should have written better.”
Zombie Software Needs Rewrites, Again and Again
According to Standish Group’s Chaos Report, 94% of software projects are redeveloped from scratch more than once. That’s huge. Similarly, when I look at the products I worked on in the past, I see that almost all of them were rewritten from scratch with newer technologies, architecture and design. Rewriting is so common in the sector that often enterprise companies see it as the only option in project management and innovation. We write, rewrite and rewrite, again and again.
We have to understand our biggest enemies in software development. In the software world, being fast is vital. Not only being first on the market is important, but also responding to customers by adding new features and eliminating bugs fast keep customer satisfaction high. But we all have a problem with “speed”. We assume going faster and smarter and efficiently is related with giving deadlines for the targets. We think that we go faster by working more or with more people. Therefore we either add new people, or do overtime to gear up production. Rushing makes us neither faster, nor more productive. Rushing increases stress, distracts focus and destroys productivity. We need creativity, effectiveness, and focus instead.
Software development is damn hard and complex. We cannot get rid of complexity. Therefore we have to live with it. The need for speed creates an unstable, unsustainable environment, makes us stressed, less focused and less productive. It just doesn’t work. Team capacity, masterplan, estimation, fixed working hours, deadlines and velocity concepts are imaginary; incompetency is the reality. Delivery times have a direct dependency on people’s skills, the efficiency of processes and the quality of output. Most of the time, developers give hidden deadlines for themselves, without any real need.
At the end of the day, we get legacy software. The pressure of deadlines combined with incompetence leads to legacy software, the dead-end of a working software. I’ve been using a different term for legacy software for a while: zombie software. Zombie software fits better because this kind is literally dead, but seems to live in production. It works at production and people gain money from it, but it needs the blood, life and energy of software developers to continue working somehow. Developers are too scared to touch it, therefore if it works, no one wants to change it.
Robert C. Martin has a perfect saying about symptoms of legacy software at twitter: “If your software is getting harder and harder to develop, you are doing something wrong.” While rushing, we are destroying the quality so much that every step we take forward makes the whole progress and flow slower than before. I believe slowing down until we reach a sustainable page is the only way of going faster.
Rushing is Evil in Software Development
As Robert C. Martin mentions on the primary value of software at CleanCoders, “The ability of a software system to tolerate and facilitate such ongoing change is the primary value of software”. Rushing is evil in software development. Any attempt to rush causes dramatic damage in productivity, focus, people’s effectiveness, adaptation capability, and tolerance of software.
For instance, we always have time for fixing bugs, but no time for writing tests. We don’t refactor and write tests because we don’t have enough time. But we have time for debugging, hacking code and fixing bugs.
We focus on processes so much that we often forget the main asset in software development: people. Processes help people to improve the way they build products, increase motivation and cultivate a healthy environment. In the end, the efficiency of processes is important, but people are crucial.
We have to admit that nobody and nothing is perfect. Customers, bosses, managers, team mates, business people, even you yourself, are far from being perfect. Requirements, documents, tools, code, the system you built, and the design, can also never be perfect. Therefore, we have to stop rushing and speeding up without control. The only way of going faster at a sustainable pace is slowing down, in three important areas:
- People for improving professionalism and craftsmanship
- The process for improving adaptation and efficiency
- Product for improving automation and quality
Areas to Slow down in When It Comes to People
Processes and tools do not build products, but people do. We have to admit, “talent hiring” is the most important functionality of an organization. It has direct impact on the future of the company and the product itself.
Hire the best talent for your organization. By saying “the best”, I do not mean the smartest, or most experienced people around. I look for passion, discipline and motivation at a minimum. If all three exists in a talent, the other skills can grow with ease. Hiring is a win-win process, so both sides should gain from the process. So you should slow down your hiring process and invest on improving it. People join companies in which they believe. So model the behavior you want to see. And through your company culture, your vision and people, make talent believe in you.
Ego is a cyanide and kills your organization slowly. Never allow ego enter the door in your organization. From lovable fools to genius jerks, never allow extremes to join your team. Never hire people with ego too. With these people, you can never build a company culture which people admire.
Stop working alone and start working together. Never allow silos to occur, because silos or hero developers are the symptoms of dysfunctional organizations. Sit together, closely. Define team standards together. Work in pairs and mobs; review together. Let the responsibility be shared in the team.
Practicing together is the most efficient way to improve your skills. While collaborating, not only do we inspire people, but also we learn from each other. Organize code retreats, randoris and coding dojos regularly in your team. Spend 30 mins of each working day for just practicing.
Let the knowledge flow among people. Learn together. I’ve been organizing Brown Bag / Lunch & Learn sessions since 2010 every week in the teams I worked in. I heard twice, at different times, from my colleagues, “joining sessions every Wednesday allows me to improve myself and that motivates me a lot”. That reflects the power and impact of regular internal meetups in companies.
Collect and deliver feedback. To gather collective feedback, you can organize Grand Retrospectives as I have done for years. By the way, Grand Retrospective is a new type of retrospective for digging into problems, with more than 20 people.
Teaching and sharing is the best way to master a topic. Be a speaker and give back to the community.
Developers seem to hate documentation, but in reality, it is the opposite. Any output people read is simply a documentation; from the production code itself to test code, from commit messages to commit graph, from log messages to error messages, developers document a lot unintentionally. So whatever you document, since people read it to understand, do it better.
You are not children. Companies are not your parents. We have to own your career and invest in yourself. If investing means spending time and money, then do it for yourself.
How Can We Optimize Processes by Slowing Down?
Every single day, we face with new challenges. These challenges should not be just about market needs or new requirements. Technical challenges also have a great impact on our progress.
Plans are nothing, but planning is everything. Do plan and revise often. Especially at the early phases of startups, you need extreme agility. One alignment per day, like via daily Scrum or daily standups, is not enough. You have to collaborate closely, work in pairs, and align more than once everyday. Keep your iteration length short, as short as one week. Create multi feedback loop channels by organizing regular review & demo sessions.
Define short term goals and long term purposes. Short term goals create focus for your team, and long term purposes prevent distraction from the focus.
If you want to understand where you are going wrong, start by visualizing the flows, both technical and business-wise. Visualize failures and fuckups to boost your learning from past experiences.
Never make decisions from your gut feeling. Always collect data, analyze and make your decisions based on data. It is also important to allow every developer to access product & code metrics. This increases collective ownership and common sense around product development.
Waste is anything you produce that has no business value. Detect and eliminate waste in the office, in your code and in the processes you follow. Boy scouts leave campgrounds cleaner than they found it. The same philosophy is valid in software development too. Follow the boy scout rule and leave your code cleaner. When you open a file to add new functionality and notice an issue there, fix it without getting any permission. Do not forget to write tests before fixing the issues. This makes you feel confident and comfortable touching your code.
You can detect waste at every single point in the software development lifecycle. Obey your definition of done and eliminate “90% done, 90+ remaining” tasks. Never allow long living branches. Long living branches are considered evil. Do not verify your code by manual testing. Manual testing mainly validates the happy path. All other scenarios can only be validated by the test code. So take it seriously.
How Can Slowing down Improve the Quality of Products?
One thing is clear. Without having a quality codebase, you cannot be agile, sorry. The first thing you need to do is eliminate technical debt and resolve bugs. If you need to stop building the features for a while, and focus on eliminating bugs.
“Fixing bugs and deploying to servers afterwards” is not a proper procedure today. It contains risks and danger. We need a better and more disciplined way of doing it. When you want to fix a bug, first write a test and reproduce the problem programmatically. Then fix the bug and see that the tests are passing. Deploying to production is safe afterwards.
I worked in teams which were spending almost all their time bug fixing and maintaining codebase. These teams suffered from production instability. To continue developing new features while fixing bugs, you need to separate your team into virtual teams. For instance, we select two teammates every iteration to deliver direct technical support and to continue fixing bugs. We call them Batman & Robin. No matter what kind of features you are rushing, bugs have to be fixed without any break.
Today, developers commonly use one practice to slow down the progress, in order to speed up. That is using pull requests. They stop the production line, do verifications and code reviews to improve the code quality. They never deploy unreviewed code to production.
Our ultimate aim should be to achieve continuous delivery, and release frequently. From git branching mechanisms to deployment strategies, from feedback mechanisms to automated testing practices, it requires a different mindset.
The practices you use at your SDLC indicate how fast you develop. For git branching mechanism, the philosophy “commit early, commit often, perfect later, publish once” and trunk based development with feature toggling let you eliminate waste.
I’ve been using TDD for years. Many people complain to me about the impact of TDD on programming speed. Joe Rainsberger shared his thoughts about TDD on twitter: “Worried that TDD will slow down your programmers? Don’t. They probably need slowing down.”
TDD has more refactoring than testing, more thinking than coding, more simplicity than elegancy. That’s why it leads to better quality. Develop by TDD; have just enough tests and simple design.
Have you ever reached 100% code coverage? I achieved this at a three-month project. I wrote unit tests to every single line of production code. At that time, I felt like a hero with super powers. But when we deployed to a pre-production environment for UAT, we noticed that four features were not working. I had to write integration and functional tests to detect the bugs and solve them. Then I realized that unit tests do not guarantee good design and working functionalities. Stop calculating code coverage. Code coverage rates are nothing but stupid information radiators.
Fix the bugs if you need 30 mins or less to fix them. Additionally, use 20% of your time eliminating technical debt.
We usually write code for not changing it in the future. Therefore when we design software, similarly we select technologies and tools for not changing them in the future. But we are wrong. Refactoring should be at every stage in our development process. As Kent Beck says, we have to do easy changes to make the changes easy. To achieve that, we govern all our microservices in a mono repository. Mono repository is for making refactoring easy, and that is what we really need.
Any design decision taken before it is required is wrong. Therefore we wait till the most responsible moment to take action. We use hexagonal architecture to active loose coupling and high cohesion at high level design of the system. That also leads well-designed monoliths. By the way, monoliths are not evil, but bad design is. We always start with a monolith and with the help of ports & adaptors, we extract some functionalities as microservices. As Martin Fowler saysin the “Monolith First” article at his blog, “going directly to a microservices architecture is risky, so consider a monolithic system first. Split to microservices when and if you need it.”
Slowing down to Go Fast as a Philosophy
Andreas Möller mentioned how he feels about software development in a tweet: “I don’t want to write code that just works: I want to write code that is clean, maintainable, easy to understand and well tested.”
To achieve that, we need to focus on three areas: people, process and product. By slowing down on people, we aim to improve professionalism and craftsmanship. By slowing down on process, we aim to improve adaptation and efficiency. And by slowing down on product, we aim to improve automation and quality. When we focus on these areas, we start to cultivate a development culture enabling software development fast.
We should not forget the followings. Working software does not have to be well-crafted. Only good professionals can build well-crafted software. And only well-crafted software lets you build features faster than ever.
Author: Lemi Orhan Ergin