This post was originally written for Must Win developers. It outlines the traits we look at to identify and promote Winners within our organization. It’s based on traits we’ve identified in our best developers.
Despite being oriented at Must Win employees, embodying these principals will help developers in any real world workplace to improve quality, communication, and the timeliness of project deliveries.
Lay the groundwork first
A good initial architecture will save you from tons of technical debt as a project grows. Without canonical answers to common questions like “where do I put this database query?” you end up with them scattered all over the place. Often, developers will use a framework to decide some of these things, which is very helpful, but there are a lot more questions that should be easily answered by the architecture for developers new to the project.
These things should all have good answers:
- Where does <X> kind of file belong?
- How do I write/run a unit/integration test?
- How do I build the application?
- How do I bootstrap the application locally? Is there good test data?
- How do I deploy the application? How do I debug a deployment?
- What do the domain objects and their relationships look like?
- What design patterns are we using?
The best developers will have established strong opinions on these topics and enforce their conventions over a project’s lifecycle by making it obvious how to do these things through examples and good introductory documentation.
Optimize for iteration time
Write a test
Many a developer has felt the need to “do it live” by testing their changes on a live deployment. This often feels easier — and work-wise it might be, but it often indicates a deeper problem. Typically there’s a complex system somewhere that’s hard to simulate (or isolate), so building a test scenario for it is complicated. This causes developers to take a shortcut, thinking it will only be one quick build-and-deploy to staging to test an issue. Code usually doesn’t quite work the first time, so it turns into several build-deploy cycles. By then, hours and several coffee breaks have passed while waiting for builds between “brief” test runs. The best developers would’ve spent those hours making a fast way to test this system, because waiting 30 minutes (or 3 minutes, whatever) for your entire build before you can test something is stupid. Especially when someone else on your team will also need to test this thing in the future.
Write a test for your code so you can debug it locally. You get a test and you’ll save yourself and your team hours of more painful debugging in the future.
A lot of things are very time intensive for developers. Creating standardized, scripted ways to perform regular tasks will save time (and mistakes) down the line. Things like data seeds, data migrations, building, testing, configuring and deploying are all good candidates.
Don’t get too carried away though, it’s always good weigh the costs/benefits.
When a pesky “TODO:” item rears it’s ugly head, actually resolve it occasionally. If you catch a bug with a one-liner fix that has nothing to do with what you’re working on — make the change. If a couple hours of refactoring will make a piece of code a lot more testable, just go ahead and do it.
This is like broken window theory for code. If it’s nice everywhere, people tend to keep it that way. So be a good neighbor.
Don’t be blocked
The usage of “blocked” is often an excuse that unproductive developers use to describe a situation they should have avoided in the first place through good planning and better communication.
Know your pre-requisites and be sure you get them
It’s common for senior developers to get a large, poorly defined problem to tackle. Often, these problems involve other teams or black box products or processes that need to be in place and functioning well for them to achieve their goals. It’s important to identify these as early as possible in development and to keep tabs on their integration progress. Inevitably something you depend on slips, which will push the project timeline back too if you’re not prepared to handle it. Exert whatever influence you have to get things done, even when doing so is not exactly your job. If you can’t get it there yourself, escalate the issue.
There’s almost always something you can do to contribute. Have a few things on the back burner so you can swap one in if you need to. Twiddling your thumbs can be fun for a while, but your team mates don’t like watching you doing it.
Weigh your constraints
The solution to any engineering problem is always driven by constraints. If you only have a week to do something, you’ll take a different approach then if you have a month. Different decisions will be made to save that time, and that will mean there will be some trade-offs. Sometimes writing perfect code isn’t the answer — correctly identifying when these situations arise will save you buckets of time and mean you don’t blow your budget on non-essentials.
Think before you code
Often, junior developers will dive into coding immediately and let the structure of their code be emergent. This is always a mistake. Have a reasonable idea of how to solve your problem before writing a line of code. Sometimes this involves a lot of research into existing solutions and strategies, or even just looking for paradigms to form the basis for your solution.
Often specifications you receive will be ambiguous. It’s important to ask for details if the goals are unclear. It’s a good idea to read a ticket, create a plan for your solution, then confirm that your solution is a good one.
If you’re working on something and think of a way it could be better, it’s literally your job to do something about it! Share your criticisms with the team and come to a consensus about a solution.
Rather than asking open ended questions like “what did you mean by X?”, it’s much more productive to say “Is this what you meant by X” while providing illustrative examples. The first answer means you’re waiting on someone else, the second answer means you can make some headway while also clarifying the situation. This is valuable because solutions that actually exist have a lot more momentum than solutions that might exist in the future.
Follow our process
Most people only use this to say what they’re working on. There’s some value in that, but you can get more by adding some accountability. You say what you got done yesterday, comparing it to yesterday’s standup, and you set your goals for today. Spend a few minutes making an agenda for your your day and post it for everyone to see. Set realistic expectations for yourself and complete them. People will love you for it.
Team chat room
We use Slack to communicate with each other. It’s your job to be up to date on what your project team members are talking about. If the team makes a decision in chat, you should know about it. It will help you understand what’s going on with the rest of the project, which makes you more versatile for the team. Versatility is a hugely valuable trait in our projects, and it means you won’t get pigeon-holed into a small corner of the code base.
Keep up with Github issues and PRs
We use a pretty typical open source model where developers work on an issue, open a pull-request, someone reviews that PR, then it gets merged to master.
Following commits other people are making and code reviewing PRs will improve your understanding of the project and keep you involved with architectural or systematic decisions. It improves your code quality and the decisions you make as a contributing developer.
Track the client value in Scoreboard
At the end of each workday, we bill our hours in Scoreboard, our time tracking tool. Remember that our clients see these messages, so you’re not just listing ticket numbers that clients may not have access to, and you’re not just putting in two words about what you worked on. You’re literally justifying the cost of your line item by describing the value you created for the client by your work that day. Write these so that our clients understand what you’re doing and why you did it.
Collect feedback often
Expecting that everything is humming along being perfectly built exactly as imagined is an easy way to be disappointed when the final product is received. Regular check-ins are good for everyone in a project because it keeps everyone running the same direction. Priorities can shift and designs change when people use them in practice. These things are normal, but developers need to talk to their clients to notice when these events happen. If this doesn’t happen, it leads to rework and late project deliveries.
Demonstrate regular progress
Very few developers can deliver perfection after a week or more without feedback. Whomever the client is for a project, they need to be kept in the loop regularly to make sure the Right Things are being delivered. This is also a good sanity check. If you can’t demonstrate something every week, then the approach to solving the problem is probably not a good one and should be revisited.
At the end of the day, a developer’s job is to provide value to their clients, whomever they may be. Typically that’s a product manager or a team lead. We’ve built up some account management best practices that everyone on your team should follow. PMs and leads love developers that can do these things well.
This can’t be stressed enough. The software ecosystem changes all the time. To stay relevant, developers must continue learning. New tools and paradigms emerge all the time. They’re not all pragmatically useful, but occasionally a new framework will make a team many times more productive. Identifying tools like that for an organization is incredibly valuable in productivity enhancements.
Learning new things also makes you as an employee more versatile, which is very valuable in a consulting environment wherein we work on many different platforms.
Master your tools
Developers that don’t understand how things work build less performant and less maintainable products. Whether you’re a junior or a senior programmer, you still have to read the docs and fully understand how your tools work.
We see developers all the time mis-applying paradigms or not understanding framework fundamentals. Think of frameworks as dangerous power tools and respect them as such. You need to know how to use them properly to be effective. Often, a simple google search “how to do X using Y” will save you lots of time, but it’s not enough to copy, paste and pray. A firm understanding of why things work the way they do will allow you to absorb and apply code effectively from other places.
Adopting these practices into your team keeps everyone sharp and creates a very engaged and efficient working environment. Applying them consistently takes some training, but it’s well worth it.
Must Win is usually hiring developers. If this sounds like a great way to work, then reach out to email@example.com and reference this post
Mike Ihbe is a founding partner of The Must Win All Star Web & Mobile Consultancy.
Mike is an expert in a wide array of technologies and has loads of experience managing fast-moving dev teams, designing systems, and scaling large applications. When not on the job, he can be found cooking delicious meals on ski slopes in exotic locales.