22

In programming we're often faced with a choice: cover each conceivable use case individually, or solve the general problem:

XKCD - The General Problem

Its obvious that solving the immediate problem is faster, however creating a generalized solution will save time in the future.

How do I know when it's best to try and cover a finite list of cases, or make a generic system to cover all possibilities?

6
  • 5
    Why so many downvotes? Commented Aug 19, 2012 at 15:20
  • 3
    Seems like a reasonable question to me. It does look like you have an unfinished edit though; you might want to take care of that. Commented Aug 19, 2012 at 17:38
  • 1
    Possible Duplicate: Rule of thumb for cost vs. savings for code re-use
    – gnat
    Commented Aug 19, 2012 at 19:42
  • @gnat that's between different programs/projects. I'm asking about in the same project/scenario. Commented Aug 19, 2012 at 19:49
  • Too vague. Covering all cases is solving the general problem. After that, it's just a matter of how you write your code.
    – Caleb
    Commented Aug 20, 2012 at 5:45

6 Answers 6

32

First, you pass the salt. Then you pass the pepper. Then you pass the grated parmesan cheese. At this point, you have enough experience to start developing a general condiment-passing system.

It works in software projects in the same way: use special purpose systems that you develop as your learning steps to generalized ones, so when it is time to start your general-purpose system, you have a better confidence in what you are building, because you have several special-purpose systems under your belt.

3
10

How do I know when it's best to try and cover a finite list of cases, or make a generic system to cover all possibilities?

Experience.

The only way to know is to have tried one path before, seen how it's bitten you in the ass (or you've wasted a bunch of time). Repeat until you get bit in the ass less.

Even then, you don't really know; you just have a better guess.

4

To build on the answers from dasblinkenlight and Paddy3118, if you don't have multiple cases to implement, then you don't need to generalize! The reason the XKCD cartoon is funny is that it lampoons premature generalization. Upon being asked to pass the salt, the unseen character immediately leaps to "developing a system to pass arbitrary condiments" when all the first character asked for was the salt. This is a good joke for developers, since I think we've all seen cases of premature generalization.

The principle opposed to premature generalization is YAGNI (You Ain't Gonna Need It). There are many materials about this available on the web, but basically YAGNI points out a number of risks in generalizing without the benefit of several actual use cases at hand, including the possibility that multiple use cases might not actually appear. Or, more subtly, the lack of actual use cases requires one to make assumptions about what's necessary in the future. These assumptions can be, and often are, incorrect.

2

It seems easier to be generic in the small, i.e. don't make a class to handle a lookup table that maps integers to strings when you can make a reasonable dictionary class that handles any pair of types (where the first type supports some type of comparison).

In a previous life I did a lot of industrial automation projects for machinery that handled a continuous web of material. Steel, aluminum, paper, plastic, ... . You unroll it at one end and roll it up again at the other after doing something useful in the middle. In one industry you start at the "payoff reel", not the "unwinder". If you use the wrong terminology then you're an idiot in the client's multi-million dollar eyes. You would be amazed at how little could be abstracted for reuse from one project to the next. OTOH, one could often create a framework or template as a starting point. It would be customized for the job at hand, but at least it had the benefit of learning from prior projects. And everyone on the team knew where we were starting from.

2

Do it once, do it twice, do it three times, generalize.

1

One, two, many!

On the second case you should be thinking on generalization. On being asked for the third you should supply it from the generalized code and use the first and second case previously solved individually as test cases.

Not the answer you're looking for? Browse other questions tagged or ask your own question.