views:

119

answers:

7

This is not a direct programming question, but a little help from the programming community would be appreciated.

I am suffering from an overgeneralization disease. I can't stop spending valuable time with making my code most general and abstract. I could also call it the toolkit/library disease. I tend to turn every programming task into a general problem and try to "write a toolkit", that would work for many similar problems.

I know it's a good thing in general, if there is enough time, but sometimes I should be writing a quick prototype and just can't seem to write the quick and dirty code that just works for the special case. I often get excited about an idea that makes the code more general and user-configurable and understimate the time it takes to actually implement it that way.

Does anyone else have this experience? How can I force myself to find the right balance between "quick hack" and "nice solution"?

+3  A: 

Write quick and dirty and test if it works, refactor until you aren't ashamed of the code.

svinto
+3  A: 

Test-driven development (aka TDD) can be a useful counterbalance to an excessive push for generality -- it instills a practice where, to quote the wikipedia entry I just pointed to,

It is important that the code written is only designed to pass the test; no further (and therefore untested) functionality should be predicted and 'allowed for' at any stage.

Once you've practiced this strictly for a while (best, if feasible, in pair programming, where the partners reinforce each other's motivation to follow the practices!-), you can move beyond this.

It's the usual cycle of learning: shu, "retain", where you practice one technique until you've mastered it; ha, "detach", where you balance techniques with each other; and finally ri, "transcend", where you move beyond such explicit learning, having mastered and internalized it all -- it works just as well for programming, as it does for the No theater for which it was originally conceived (most people in the West who are familiar with the shu-ha-ri concept have probably met it in the context of martial arts, but, historically, that was already a huge extension of the original;-).

Alex Martelli
A: 

This, I think, is a problem that many programmers face. That is why we need project managers that understand business. Unfortunately, we work in an environment that is not purely academic. So the work we do is only useful if it satisfies the business requirements in a timely manner.

You have to find the right balance between doing code "right" and actually delivering working software.

Vincent Ramdhanie
+3  A: 

Meet your deadlines. And if you don't have deadlines, create your own.

Programmers don't work in a vacuum, they're there to serve a business need most of the time.

I usually get a rapid delivery solution done first then, provided I have time, I begin the process of cleaning it up (making sure not to break the functionality. The last good version at the deadline is the shipping version.

Trust me, the first couple of boots in the rear-end or other bad performance appraisals will educate you on the importance of this :-)

paxdiablo
+3  A: 

I tend to do this too. But when I come to use reuse my "generalised" code, I ususally find that it's not quite what I need in the new situation.

These days I try to wait until I've implemented something a couple of times before thinking about how it should be generalised. That way I have a better idea of the real use-cases that I should cover.

The question also reminds me of the quote from Charles Moore in this blog post. Every time you reimplement something, you learn more about it, and you improve your implementation. You probably should reinvent the wheel a few times before you stick your implementation in a library.

Blorgbeard
+1  A: 

Working code is better than well designed, but non working code. Even the crudest implementation is much better than something that does not work or is not even finished.

From the prototype/quick and dirty implementation it is easier to do refactoring and structural improvements, since there is a working reference to test against.

As others have written, TDD is very useful since without proper tests its very hard so succeed with any refactoring project.

But finally, it is very important to separate generalization within the problem domain your program is running and generalization within the whole domain of computation.

Very often projects end up with reinventing solutions to data structures, algorithms, network protocols etc instead of using existing implementation/libraries.

I have seen numerous examples where programmers implement their own hashmaps, http implementations etc, instead of using existing ones. Sometimes maybe there was a lack of compatibility between a library and the application, but then the facade pattern could be used to encapsulate the usage of an external library.

Ernelli
A: 

Best answer I've always found is how long does the code have to last? You don't necessarily have to write an entire framework just make sure that its maintainable.

Danny