In the real world, at least mine, once it works you get pressure to move on. Both my own mind saying, it works so it's good enough, and external pressure from a stake holder who says it looks good lets move on. I don't feel like I get to that latter 20% - 30%. As such, I try to be thoughtful on my design, but I also realize the need to get stuff done. It's a balancing act.
The pressure you put on yourself is your responsibility. Don't pretend it's something you have no power over.
The stake holder should be your customer, not your boss. Even if that dynamic is broken, you don't need to tell them it's shippable until you're happy with the code.
True, we are the ones responsible for our integrity and we often live with our mistakes, paying for poor design choices during later maintenance cycles.
Just be aware that it can be easy to get lost in a yak-shaving exercise doing your cleanup refactoring. I recommend timeboxing this phase to no more than an hour, or prioritizing one or two specific tasks so that you don't go off the deep end.
Don't forget that others are depending on you to get their work done. There may be a 2-hour cleanup task somewhere else in the code that will help your teammates far more than the itch you want to scratch here and now.
> I recommend timeboxing this phase to no more than an hour, or prioritizing one or two specific tasks so that you don't go off the deep end.
When I read comments like this I think to myself "How can they possibly be so productive that refactoring can be done inside of an hour?".
Then I remember that some developers split up projects/problems into really small components and can complete a feature or two in a single day. Well then an hour is actually a fair bit of time to spend refactoring.
Yeah, I don't see a lot of talk of how hard it is to clean up code. A lot of programmers just aren't good at it, so maybe it's just as well that they don't do much of it...
"Convert your working code to good design" is not a trivial task, and like you say, a big part of it is to pick your battles.
Sometimes cleaning up code has positive business ramifications - for example, I took the time to design a component carefully in the past few weeks for work, and when it came to start a new user story for a nearly identical feature for another view, the careful cleaned up design carried over seamlessly & got finished in about a day of work. This will be assuredly reused again for another feature with nearly identical logic/models, and thus saved the company almost 2x the time of development.
Sometimes you just have to argue for the effort being expended, and my managers all had the foresight to push for doing it right when it had large ramifications.
Yeah, sometimes even though it works from a functional stand point, you can say it 'isn't working' and still be honest to yourself, since the messy code won't work in terms of long-term maintainability.
The trick is to think of the last little bit that makes it complete in terms of the 'cleaned up' approach, which means you bake in the cleaning up/abstracting as necessary for completion.
When I use the word done I mean done to the point that I'm marking the task/project/module done and telling someone it's done. It's not like a PM is checking the CI server and noticing the build is green and the unit tests pass and telling me to get on to the next task...
There's done as in the spirit of the assignment is completed to a satisfactory level of cleanliness and then there's perfectly done, which means you'll never ship it. I think that's hard for a lot of people to come to terms with, people of all skill levels. The code needs to be easy to navigate and the patterns should be as easy as possible to learn and emulate for others entering- but you don have to start there, you just need to wind up there before you call it done.