Software developers created the idea of an “antipattern” to warn others what not to do. Think of the “Dragons Be Here” label on old maps. Whatever you do, don’t sail your ship here.
Years of hard-won experience are boiled down to a concise description of how not to structure your code, how not to imagine your architecture or how not to design your database schema. These antipatterns have become so useful that they’re passed around among developers with as much reverence as functional design patterns that describe how one should do things.
Software project management has its own “antipatterns”: Seemingly sound practices that hard-won experience suggests we shouldn’t actually do. Running a project and managing a team is less of a science than spinning up code, of course. Some antipatterns are mirror images of each other: They command you to embrace and eschew the same thing. But what they’re really asking for is moderation. Too much of any idea — no matter how good it might be — doesn’t work so well in managing teams.
Here are 11 antipatterns of software development management. Think of them as seemingly sound habits to be avoided when herding the cats you call developers.
The ‘there’s no I in team’ antipattern
Robert Frost liked to say that good fences make good neighbors. We need our own spaces and the same is true for developers. There’s always the temptation to add more developers to a team under the hope that many hands will make light work. But all too often the developers end up conflicting with each other, fighting to update the same sections of code. Suddenly the code reviews get stacked up and no one wants to go through and merge the code line by line.
The microservices architecture has many flaws, but it can give developers room to breathe. They can work independently on their own corners of the code. They can commit their code, create tests and move forward without trying to synchronize their steps. Splitting up developers and letting them work in their own space makes all the difference.
The ‘divide and conquer’ antipattern
The only problem with keeping developers apart comes when they finally need to get their code to work together. Suddenly one API delivers strings while the other wants integers. Or maybe one team expects data in rows while the other expects it in columns. There are so many ways that a quick sketch on the white board can be interpreted. And, of course, the tests all pass because each group wrote the tests for their own code using their own vision.
The solution is more central control and more centralized testing. Some teams designate some developers to constantly monitor integration to ensure that all of the parts are coming together as smoothly as possible. Getting the parts to work together is as much work as building the parts. Keeping the developers moving in the same direction is a job in itself.
The ‘follow your vision’ antipattern
If I had a dollar for every moment when I imagined a beautiful, shimmering pile of code in the distance, well, I would be able to hire a team of developers to create it. Every developer knows the burst of creative genius that delivers the whole vision for the entire stack. Every developer also knows this is followed by a period of imagined super powers where every feature seems like it can be knocked together in just a few lines of code. How many times do we just fire up the code editor and start running toward this shiny mirage?
This is why we need a methodology — something that forces us to set aside the glorious dream and to sketch out the plan in detail. Then we can start to recognize the flaws when we return the next day or next week. Planning may be a real chore but it’s faster than debugging code. Don’t just do something. Sit there.
The ‘go by the book’ antipattern
For every methodology, there are books, conferences and consultants ready to tell you what you absolutely must do and what you must — at all costs — avoid. They are very good at delivering these rules with absolute authority.
The trouble is that nothing fits their rubrics perfectly. You can write specs for months, but you’ll always discover some new angle or issue when you’re almost finished implementing them. You can try to stay flexible and agile, but then you fail to anticipate something that would be much easier to fix during the planning stage. There’s always a gotcha.
The best managers choose a methodology and then find a way to anticipate where the methodology will fail. None of us can do this all of the time, but when we do it sure feels like we’ve found a way.
The ‘trust the process’ antipattern
While software development has its moments of magic in which everything comes together on time, not keeping track of the details for fear of messing with the creative process can have consequences. How long has the new database installation taken? When did that team promise to redesign the single sign-on API? How many people are working on checking in code to refactor the technical debt leftover from the last code sprint?
The people responsible always have a long list of roadblocks, hurdles and issues that have delayed it. The challenge for leadership is to find a graceful way to watch what is happening and keep track with just enough detail to make intelligent decisions. The software development metrics can be quite imprecise but as long as you don’t expect too much, they’ll let you follow who is working on what.
The ‘you can’t manage what you don’t measure’ antipattern
It’s an old slogan that sounds fresh today, thanks to the growing spotlight on the importance of data. And it’s not that software metrics are bad; they just don’t do a good job of capturing all that is going on. Long ago, managers tried to count the number of lines of code that the developers created and the developers quickly figured out how to add extra comments or other non-functional tidbits to multiply their output.
These days some managers assign abstract “points” to tasks and then tally up the points at the end of a quarter or year. But figuring out the right number of points is almost as hard as solving the problem in the first place. The most hardcore teams ask developers to bid for work in points, pitting them against each other in the quest for more accurate assessment. This doesn’t help team camaraderie or collaboration in the least.
The biggest danger is that developers avoid the hardest or most unpredictable tickets knowing that they’re just swamps that won’t reward them with enough points at the end of the quarter or year. The solution is to not place too much faith in these metrics. Track the number of points, if you will, but don’t treat them as the absolute measure of worth.
The ‘foolish consistency is the hobgoblin of little minds’ antipattern
Developers need to be free. If you ask them, they tell you flat out that they don’t want someone clamping down on their ability to innovate and imagine wonderful new code.
The problem is that developers, left to their own devices, will head in different directions. That’s why we need some standards. The advantages of having some consistency to the code are easy to understand. The code is more readable if the patterns and visual rhythms are predictable.
The best solutions can be enforced automatically. Some code editors (Atom, for instance) use rules to reformat all code to conform to the rules spelled out. (See also ESLint.) This saves the developers from worrying about the details of standards while ensuring that the results are clean enough.
The ‘standards will save you’ antipattern
But standards can often fuel anger and resentment, giving developers another reason to fight. They love to flog the standards in code reviews, dinging lines of code for the smallest nonissues. For instance, someone at Airbnb devoted time to thinking and writing rules about where spaces are put in code. Putting a space inside curly brackets is required (19.11), but putting them inside square brackets is forbidden (19.10). If you think developers won’t spend time fighting over trivial matters, well, you haven’t been paying attention. They love to deploy the word “standard” as non-standard code could doom everyone to a death from, say, Ebola.
Many of these so-called standards are purely aesthetic and make no difference in code execution speed or whether the code will get the right answer. Extra white space is ignored by the compiler or interpreter. The worst thing you can do is push boldly for standards that make little to no difference in the quality of the running code. All of the aesthetic talk about the location of spaces is just for humans — and the goal is to stop the humans from arguing too much. If you’re going to use standards, make them simple to follow and worry only about the details with practical significance.
The ‘simplify your stack’ antipattern
One of the simplest ways to assert some discipline over the code base is to insist upon one and only one language. Everything is consistent and easy for everyone to read. Everyone is hired with the same language skills and everyone gets along.
It’s a beautiful idea and it makes sense to follow it. The tricky question is what to do when you’re tempted to break it. There’s always going to be some new library or feature-rich pile of open source code that does exactly what you want — but it’s written in another language.
If you’re strict, you’ll maintain the purity of the code base at the cost of accomplishing something quickly and efficiently. In the end, users don’t read any of the code. They just care about what the code does. Sometimes it makes sense to tolerate a bit of divergence in the code base — if it makes the users happy. The challenge is knowing when the tradeoff is worth it.
Chris loves new functional languages, the stricter and more type-checked the better. Pat wants to write close-to-the-metal code that’s almost machine code. Bob loves whatever was in the last headline.
Be careful with being too open and accommodating.
The ‘motivation is the key to success’ antipattern
Why was the guy next to me writing twice as much code instead of adding a standard library that would do the work in one line? Because the bosses added a tripwire to the git repository forcing an extra level of review for any additions to the library directory and the guys doing that review were known to be capricious jerks.
A few weeks later, I saw the same guy deftly argue to split a ticket into multiple parts worth twice as many “points,” the virtual reward that everyone was trying to accumulate to justify our salaries. He was a master at maneuvering through pull requests, support tickets and agile metrics.
So while it may be true that motivating a team is vital to the success of a software project, it may be a riddle wrapped inside an enigma to figure out what truly motivates your developers. We can try to corral the developers and herd them toward delivering what the customer ultimately wants, but the developers have minds of their own. They understand these tools better than we will ever do. The best we can do is cultivate a sense of partnership and seek to nurture their understanding of the big picture. Then we cross our fingers and hope they’ll do their best to translate the abstract goals into millions of lines of clean, tested and relatively bug-free code.