Thursday, June 02, 2005

"It seems more complicated now"

A lot of programmers still believe in procedural programming even if they use an object-oriented language like C++ or C#. When you eliminate duplicate code, you can do it quite often by taking a big long procedure and replacing it with some objects. Consider this code:

for (i = 0; i<things.count; ++i)
{
Initialize( thing[i] );
}

for (i = 0; i<things.count; ++i)
{
Continue( thing[i] );
}

for (i = 0; i<things.count; ++i)
{
Finish( thing[i] );
}

There is clearly duplicate code here. Three times we run a loop over things. You can't just refactor all three calls into one loop, since the processing of the latter loops might depend on the first loop being finished.

So how do we remove the duplication? Let's create an abstract object, AThingProcessor, and use it to do all of the looping:

class AThingProcessor
{
void Run()
{
for (i = 0; i<things.count; ++i)
{
ProcessThing( thing[i] );
}
}

abstract void ProcessThing( thing t );
}

Now we can replace each loop with an instance of a class, for example:

class Initializor : AThingProcessor
{
virtual void ProcessThing( thing t )
{
Initialize(t);
}
}

And now the original code can be replaced with:

new Initializor().Run();
new Continuor().Run();
new Finisher().Run();

So what is the result? Our original code is now much more object-oriented and flexible. But without knowing the definitions of Initializor, Continuor, and Finisher, you don't know exactly what is happening here. The result is, some programmers will look at this code and say "It seems more complicated now". But it really isn't. It's just more object-oriented.