Yesterday I wrote a little PythonLanguage
program to convert a configuration file from an old format to a new format: about 100 lines, mostly just reading lines, running them through regexps and outputting XML. I'm putting it in the repository in case somebody else wants to see it, but I doubt it will have to be used again.
It probably qualifies as a quick hack: there is no abstraction in the data, just dictionaries of lists; several special-cases hardcoded in; and it's not split into methods. If I kept at it for a few more minutes I'm sure I could make it easier to understand and more reusable.
For the time being I'm chosing not to do that, and finding that quite an interesting experience. I think for me it is therapeutic to remember that some programs must be cleaner than others; that I can refactor next time I work on it. In some ways the program is simpler when it is a hardcoded text-processor than it would be if it parsed the old file into objects, manipulated those objects, and so on.
On the other hand it would be terrible if a 2kloc program was written in the same style, and I can't rule out that somebody will later need to extend it. I like to think that if that person is me I'd split it up and refactor during the changes.
What do you think?
Great topic. It can be difficult to learn which programs need to be OO-normal and which can be denormalized.
I started out wanting to apply everything I know about OO to every program I wrote. So, even when writing a quick hack, I'd spend time making it a somewhat less quick hack. If I parsed command-line arguments, I'd have an object for it. If there was an object in the problem domain, I'd make an object for it. And so on.
My extreme OO behavior cost me time, but I got away with it because I type very quickly and can belt out lots of code in a short amount of time. The main reason I did it was to instill OO habits, to make creating and using objects second nature. That worked: overusing OO is a great technique for learning it.
The advent of refactoring as a conscious strategy has given me a good tool for deciding when to engage in normalized OO and when not to. First DoTheSimplestThingThatCouldPossiblyWork
. That might mean parsing the command line right there in main. Then refactor until it's Good Enough. When writing the one-off program, Good Enough means I will understand it when I come back to it in a day or two or 10 (my experience shows that most one-offs are really run 2 or 10 or 20 times before discarding them), but I will leave any smelly code that's not actually putrid. When writing production code, Good Enough means that it has the QualityWithoutaName
. Only the faintest smells allowed.
It is important to remember that LearningMeansMakingMistakes
. When I was
learning OO programming, I acted like MartinPool
and made the mistake of
overabstracting, which was fine since I was trying to learn how to abstract
and was not trying to produce code as fast as I could. If you want to produce
code as fast as possible, over-abstracting is even more dangerous than
underabstracting. Now I'm trying to DoTheSimplestThingThatCouldPossiblyWork
and I imagine that I will sometimes do something to simple to work.
If you write a script once and it gets used for years without ever needing
to be changed, it doesn't matter how readable it is. I think it is fine
to write quick hacks and then to refactor them when you have to change it.
See also: AlternateHardAndSoftLayers