I haven’t posted on this website in a few years. The difficulties I have experienced in getting going again have made me appreciate even more the people who work full-time and still manage to contribute to the software community through blog posts, videos, and open source code. I want to write more, and actually publish. To get things started off, I would like to share some of the interesting experiences from the last few years as a full-stack software developer.
My main open source contribution over the past few years has been an Ember.js component. It’s a small project but has been a great learning experience. Many people download this addon every day, so it keeps me motivated to keep it updated. The component has had 14 contributors so far which is encouraging; it’s nice when people get involved. Someone even made a screencast explaining how to use the component, so that was a thrill to watch. It feels gratifying to know that something you’ve done is helping others, even if it’s in a minor capacity.
Last time I was looking for a job I spent months researching companies, applying, and interviewing. The pool of employers (especially remote ones) seemed very small. I had the impression that most companies had their pick of dozens of qualified people. After being involved in the hiring process at my current workplace, it’s clear that that’s not true. Hiring a software developer who is a good fit for the company is very hard. The amount of risk involved in the hiring process is huge because it takes months to hire and onboard a new person. Even senior developers have a tough time making meaningful contributions right away so you could potentially spend many months before you find out that they are not a good fit. I certainly have a lot of empathy with companies now and respect the hiring process more.
Building software isn’t too difficult. Building great software is in my opinion quite hard. A lot of the difficulty comes from having the discipline to focus on one small problem space. Everyone loves new features, so it’s easy to keep adding more and more. Removing features takes a lot of courage, so it rarely happens. Over time you end up building software that does everything but badly. This problem is especially acute when there is no unifying vision, and many viewpoints push and pull the project in different directions.
Ideally, a project has a strong vision and real actionable data that helps steer the vision. The data about how people are using the app can help the team experiment, iterate and perhaps even remove features to simplify the design.
Over the past two years, our teams experimented with many different project management techniques. Usually, this is prompted by perceived low productivity, as if adopting a new process will fix profound organizational issues. My opinion about project management is probably controversial, but it’s pretty simple: any process will do, and the simpler, the better. Adopting agile isn’t going to make your project more attractive, nor is it going to make your codebase easier to work with.
The agile manifesto misinterpreted:
“Individuals and interactions over processes and tools” somehow translates as “let’s use a process with a cool sounding acronym (SCRUM!), have daily meetings, estimate everything, and install complicated tools for managing this whole process”. The work ends up being chopped up into tiny little pieces and fed into the developer assembly line. Productivity goes up in the short-term at the cost of quality. Over the long-term productivity goes down as developers have less and less control over their work. Conveniently for managers, now every developer has a number over their head – the one they were forced to estimate.
“Working software over comprehensive documentation” sounds great if you follow the remaining two statements from the agile manifesto: “Customer collaboration over contract negotiation” and “Responding to change over following a plan.” If the organization as a whole remains invested in contracts, and scales back production after the software is “delivered,” you are, in short, delivering crappy software.
Ideally, the right people are hired, and they’re trusted to get the job done. The team needs to make meaningful decisions and have a lot of input over the direction of the project. A simple process with continuous delivery is all you need.
Estimation vs. bargaining
Estimation starts off as a “rough guess” because people need to know how much the software will cost. The healthy response to a high estimate would be to reduce scope, but that doesn’t always happen. Some people, usually out of desperation, end up bargaining with the developers. “Can you do this in less time?” is always asked and undisciplined developers, eager to please, will say “I’ll see what I can do”. Of course, the result is that software gets delivered faster by skimping on the quality. First, tests go out the window; next, refactors and quality; then UI’s go missing, and so on. What developers are doing is writing technical debt. This debt has to be paid one day – with compound interest.
Solving problems as a software developer isn’t that hard. We can deliver a “working solution” relatively quickly. If you’re working with developers, you have to ask yourself whether you want the “working solution” or a finely crafted solution that will pass the test of time. Do you want your users to grit their teeth and suffer through it or do you want them to have a smooth and memorable experience?
To produce a great product you need talented people working under reasonable expectations. The company needs to have a culture of craftsmanship.
Ideally, there’s a lack of emphasis on “process” and developers have the freedom to work on whatever inspires them. One day it might be refactoring a major piece of the code that is causing trouble. Another day it might be introducing a useful new feature or tool. The company can deliver a lot of value if it learns how to direct the passion and inspiration of the developers.
Companies need to encourage developers and reward them for standing their ground about high-quality software. Testing should be a requirement, not a “nice to have.” User experience should be paramount, not an afterthought. Code reviews should have an extremely high bar without comments like “I have to ship this today so we’ll fix it later.”