DEV Community

Yalda Khoshpey
Yalda Khoshpey

Posted on

These 5 Coding Habits Separate a Good Developer from a Great One

Over the years,working across different teams, I've noticed that great developers—beyond mastering frameworks and languages—have these habits ingrained in their DNA:

  1. 🧠 Thinking 'Why' Before 'How' They take the time to understand why a feature is being built before writing a single line of code. This understanding profoundly influences the architecture and technical choices.
  2. 📚 Documenting as Part of the Coding Process Not just for others, but for their "future self"! A simple comment, a clear README, or API docs can save the entire team hours of frustration.
  3. 🔍Intentional Code Reviews When reviewing others' code, they're not just looking for bugs. They're looking for clarity, simplicity, and cohesion with the overall architecture. Their critique is constructive, never personal.
  4. ⏱️ Time-Blocking for Refactoring They know the first solution isn't always the best one. They proactively block time in their calendar for refactoring and cleaning up code. It's an investment, not a waste of time.
  5. 🎯 Testing for Failure, Not Just Success Their unit tests don't just cover the happy path; they cover edge cases and failure states. They make it a non-negotiable habit.

What do you think? Which of these habits is the hardest to develop? Or what other habit would you add to this list? 👇

Top comments (8)

Collapse
 
emilioacevedodev profile image
Emilio Acevedo

Great list. These habits are precisely what separates simply writing code from building software professionally and sustainably.

In my opinion, the hardest habit to develop, especially early in a career, is the first one: 🧠 Thinking 'Why' Before 'How'.

It requires confidence and an ownership mindset to push beyond the assigned ticket, question the requirements, and ensure you're solving the right business problem. It's the leap from being an implementer to being a problem-solver.

If I were to add a sixth habit to your list, it would be one I've consistently seen in the most effective engineers I've worked with:

⚙️ Having "Operational Empathy" (A Production-First Mindset).

A great developer doesn't just write code for the next developer who will read it; they write code for the operations engineer or SRE who will be on-call at 3 AM when something breaks.

This translates into concrete actions during development:

  • Structured, contextual logging, not just generic messages.
  • Clear metrics that expose the health and performance of the feature.
  • Designing for resilience: What happens if this external service is down? Does the system degrade gracefully or collapse?

In the world of mission-critical systems, where I've spent most of my career, this mindset isn't a luxury—it's the foundation upon which reliability is built.

Thanks for starting this excellent discussion.

Collapse
 
yaldakhoshpey profile image
Yalda Khoshpey

Thank you for this fantastic addition. Operational Empathy' is a brilliant way to frame it. You're absolutely right shifting the mindset to the engineer on-call at 3 AM is what separates a good service from a great, resilient one. This is a crucial habit✨

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️ • Edited

Thinking 'Why' Before 'How'

This one is extremely underrated, specially when it comes to feature-requests from clients.

For those who don't know what the "X-Y-Problem" is, it's something you also see a lot in stack-overflow questions,when a user has a problem X, tries to think of a way to do it which then runs into a problem Y, which they then ask for help with; which often leads to rather bizarre questions.

When a user says "can't you add a shopping basket like in amazon", that might be a really complex feature to add, taking a lot of time and either driving up prices for the client or making the project less profitable. Maybe all the client actually wanted was a chance to double-check a list of items, which could instead be done as a single extra pop-up in an ordering process. That's a real example from a recent project.

And ultimately this goes back to the fundamental rule: always have at least some understanding of the problem domain, otherwise you and the client will end up talking past each other or you'll implement bad solutions to problems you don't even know about because the client figures that's the best way to address them.

Time-Blocking for Refactoring

Either this or the boy scout rule: if you touch some part of the code, do some clean-up work too. Often this also means refactoring things along the way. If you find yourself annoyed that extending a bit of logic requires too much effort, that's your signal that you should think about generalising the logic into something that's easier to extend.

That is, unless there's a comment that this bit of code is performance-critical and needs to be optimised at the cost of maintainability; but those are very rare cases. And of course, always leave those comments when you find yourself having to de-generalise for performance.

Testing for Failure, Not Just Success

I couldn't count how many times I've been saved by tests telling me that a certain operation failed to raise an exception; or how many times I would have been saved if such a test had existed.

A recent example was a class that zips some files with a password before sending to a client; turns out some other part of the application was failing to pass in a password at all, so the file got zipped without any password and got sent out unencrypted. Ooops! Along with fixing that, I added the test I wish I had added earlier: check that the class raises an error when the password is nil.

PS: free book recommendation for everyone who likes these sort of "x habits for developers" lists: 97 Things Every Programmer Should Know

It's my favourite programming book. It's reasonably short and all the ideas in it are relatively simple, but that also helps it condense a lot of wisdom into just one book.

Collapse
 
yaldakhoshpey profile image
Yalda Khoshpey

This is a fantastic and highly insightful comment. You've perfectly captured some of the most critical yet often overlooked practices in software development.

The "X-Y Problem" point is so true – it's a constant battle against assumptions, and learning to ask "what problem are you actually trying to solve?" is a superpower.

I'm a huge advocate of the Boy Scout Rule as well. Leaving the code cleaner than you found it is a mindset that pays massive dividends in the long run.

And thank you for the book recommendation! "97 Things Every Programmer Should Know" is a gem. It's the kind of book you can flip open to any page and find a valuable insight.

Collapse
 
a-k-0047 profile image
ak0047

Thank you for sharing this article!
I'll keep these in mind.

Collapse
 
yaldakhoshpey profile image
Yalda Khoshpey

You're very welcome! Glad you found it useful😍✨

Collapse
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

Thinking why before how seems to be the harder one. Just wrote a post about it (not yet published). And time-blocking for refactoring. Next version coming soon… you know.

Collapse
 
yaldakhoshpey profile image
Yalda Khoshpey

Completely agree mastering that 'why before how' shift is tough but transformative. Excited to read your take on it! Merci pour votre commentaire🙏🏻✨