Ask HN: How obsessive are you with your code?
So.. realized today that I probably spend an hour a day refactoring code. It's usually towards the end of the day, and includes items such as renaming variables, creating/moving classes, enforcing stricter patterns, writing in-depth comments, checking and removing dead code, and other general upkeep issues.
My question: is this too much? too little? How much time do you spend on these activities? Should I spend more time upfront thinking before coding (gasp!)?
40 comments
[ 3.2 ms ] story [ 75.9 ms ] threadProbably. But anyone who reads my blog could have guessed that I would say that.
I tend to spend a long time writing code and then never look at it again. I even forget the implementation details. It makes my life much easier -- if I had to keep thinking about how btree_node.c calls proto_lbs_client.c which calls wire_requestqueue.c which calls wire_writequeue.c which calls network_buf.c which calls events_network.c I'd never get anything done. And if I can remember all that, I'm going to think about it whether I like it or not.
Just get the code right the first time. Then you can use it as a building block without needing to worry about implementation.
So my time spent upfront may actually look like coding. Depending on the problem I may use strange domain specific languages like scribbling equations on dead trees.
The artefacts of this upfront thinking may get re-used in implementing the solution. Than it can look like refactoring.
My justification (to myself, at least) is that when I encounter code thats badly formatted, I find that the flow doesn't tend to make much sense (either to read, or as its actually executed) and it needs refactoring anyway. So, I'll fix the formatting up and read the code to see what it does. And then refactor parts, if necessary.
Neither do I, really. I don't go back to change something around unless I do have time.
And see I've been solo for about two years which means I haven't had to manage any of those external expectations that you get from being on a team.
With enough experience, you'll know how to start writing something such that it won't require extensive refactoring. Make sure it's good enough that if you don't have enough time, it's still good in these two major ways: as fast as possible with no redundancy, maintainable by someone else.
But I don't go actively looking for things to "fix". While reading code, if only one line is separating functions, I add another. I add \ to line ends trying to limit width to 80 chars.
Lately my mantra has been "Shipping is a feature". Code working is my number one priority. But like most of the people, I like to think I'm above average, so I don't believe I write _bad_ code at the first time. I know it's not perfect. Just by saying this, I remember of things I know I should change to make the code better, but why bother?
What you must always pay attention is the balance between creating value for your customer, and for you as a professional. And even when you do things for yourself, always remember your main objective is to make things easier in the future to create value for your customers.
Caveats apply, of course. A refactoring to allow more modularity or whatever in the future might be good to do now, but honestly usually there are more pressing matters (unless the current pressure is to add some module functionality).
It's hard to give any straight answer. There are no hard rules, like "you should only refactor during one hour per-day". Maybe you're doing something where a big-design-upfront is not possible. Maybe not.
These things come with experience, tough. And where you want to keep your focus. If I was working on a 10 year code base where the original programmer has left the company, and didn't document anything, then I guess I would spend more time nurturing the code. But my job today is too fast paced, and "when it will be ready" is my customers/stakeholders number one priority. I negotiated and told them quality would suffer, and they are aware, but don't care much.
Great point. By not having customers right now, I've likely started to overvalue my own development/investment.
Most terminals and monitors today will easily go to 100 chars, which is typically where I prefer to break lines. This gives room for 3-4 levels of nesting (using 4 char tabs), which is about the max depth you'd want to nest. There are exceptions of course but for the most part any more than 3-4 levels deep and you should be looking at refactoring.
Then a new member came to the team, and his coding style was not very good. I told him to read and follow PEP8, he downloaded some script which checks source for PEP8 compliance, and he really made the effort to format his code.
So, it's not something that I would personally go insane trying to keep width to 80, but when two things happened: I was already doing most of the PEP and my teammate wanted me to keep 80 chars, and I had to eat my own dogfood :) when the new person came on board.
In the end, it's something easy to do, and keep my colleagues happy.
But whenever I wade into the code for good reason, I reward myself by refactoring whatever areas I happen to touch. It's like throwing a fish to a seal. That way I always get a chance to do fun things like unifying similar code or making code more data-driven.
I'm still a perfectionist, but I'm also a strategic procrastinator. So while I'm working on code, whenever I think of anything, however small, that might improve it, I'll throw in a comment such as "TODO 0703 might want to tighten this up" or "TODO 0703 you need to test this case before releasing". I am so relentless and unforgiving that sometimes the TODOs multiply like rabbits.
Before I release anything, I grep on "TODO". As long as any TODOs show up, I can't release. If I need to put off something until later, I'll change that "TODO" to "LATER". Occasionally I'll make a point of revisiting my LATER entries, converting some of them back to TODO. That way perfection is an ongoing process, not an attained state.
Amazing what you can find when that happens :-)
Some code is obvious, no comments or naming is needed. Otherwise, be obvious or leave enough comments to make life easy for your team, or “future you.”
This approach works quite well for me, since I generally plan code in my head before a coding / transcribing session.
An hour a day sounds high, but understandable if you are working on a scrappy code-base. It sounds like you are doing a good job, especially since you will be eliminating 'code-smells', fixing warnings etc.
I always like to plug it, but Code Complete was the book that transformed my attitude towards 'my craft'. Great book, should be mandatory reading.
Though I do agree that ridding your code of compiler warnings is a good idea in general. Because when a warning comes up afterwards, it will actually have some signalling value, instead of being ignored in a sea of similar warnings.
I mean no great disrespect, but if you need a machine to remind you not to use global mutable state, get back in the oven, you're still a bit gooey on the inside.
Every time I submit a revision I try to include a change which improves an area of the code outside of my main focus.
By doing this I am constantly improving and re-learning parts of the codebase that otherwise become moldy.
So, A typical checking might be something like...
Add ability for animation tracks to play in reverse. Add missing null reference check to CalculateWorldTransform Improve per of serializer by 10% (avoid string parse for main line case) BUGFIX #1087: Keyboard input delayed by one frame
Basically, I try to make refactoring/improvements an ongoing part of development rather than a chore.
Now I run my own company and am the sole developer. So these days I tend to think if my code is well factored, I'm doing it wrong.
It's not quite that simple of course. The lower down the stack a chunk of code lies - the more things that depend it - the more I want it well factored and well tested. But I'm quite comfortable with code high up the stack being scrappy, hacky and untested.
I wouldn't revisit old code until I needed to change it for another reason, since all changes should be thought out properly.
but this is not an ideal world and from a recent thread about a similar subject, i got the impression that most of us don't like the code we wrote the second time we look at it.
i guess it's okay to spend time on code that's already perfectly working as long as you don't miss your deadlines (or arrive late to a date, or something).
In the same way I can't count how long writing tests takes I can't count how long refactoring takes as its simply part of the normal development process. I only ever account for work that includes these activities because after doing it for so many years I realise you can't split them without doing a hack job.
http://nickgravgaard.com/elastictabstops/
Then see if anyone uses it,
Then make it good.
The time to refractor is when you see a real time savings from doing so, not a hypothetical one. It works for me at least.
It gets tedious very quickly but at the same time the number of errors that persist to Unit Test has dropped considerably.
After spending a lot of time thinking about Software Process, I've concluded that the biggest gains come from engineering discipline, not heavier process, so yeah, I don't think you're doing too much. Although I wouldn't force code/design into patterns.
A lot of the code I'm modifying these days is legacy stuff with 300+ line methods!!! Although it was written by a pretty smart guy, I really wish he had heard of refactoring and removing dead code: I have a burning hatred of commented out code and code that never gets executed.