Skip to main content

Matryoshka Code

One little class in another little class in...

In programming, a very old pejorative term is spaghetti code. Traditionally this is associated with languages like BASIC, where control structure is done with a lot of nested IF-ELSE structures, combined with jumping around with GOTO and GOSUB. I've seen my share of this and I wrote my share of this too.

But we seem to have a modern variant of this, which I would like to call "Matryoshka Code". The first time this name jumped into my head was when I had to do a bit with some "Zope Interfaces" or "ZTC" style of programming, where almost everything is an "adaptor", but it can be had in your plain old object oriented programming too.

What does it look like? One little class, inside another little class, inside another little class, inside... So your code needs do do something, e.g. a payment. Great, there is a PaymentGenerator class. You feed it some parameters and it spits out a PaymentHandler class thing. Which hands things off to one of a couple of PaymentProcessor based classes (based on if it's a CC payment or some other style of payment), and the actual act of connecting to the payment gateway is handled by the GatewayPaymentProcessor class (or maybe there are multiple subclasses of this, based on which one you're using?). Which hands off to another class for processing the result. You get the point, it's like one of those russian Matryoshka toys.

Oh, and it's not limited to OO programming and classes. You can do the same with plain old method calls of course (I have a very fine example here in some of my code). Classes are just a bit better to hide the actual functionality more, as inside the class obviously things will be done in a couple of methods too.

The good part: Code is served in small portions, often classes are quite small and don't fill more than a screenfull. Frequently they are trivially small. Small is also nicely testable. "This part works, let's go on to the next one."

The bad part: Just like with spaghetti code, if you have to read through and follow the functionality, you have to follow a twisted path. You are going to open a lot of little dolls, find out which little part of the task they do and hunt on for the next little doll. Frequently some parameter is dragged through all this little dolls of code, sometimes passed as a parameter to methods, sometimes set as an instance attribute. If your task is to change or update something, you possibly have to hunt through a lot of methods to check for side effects and parameters being passed in hiding.

You might be off good to test things, because functionality is packaged in small bites, it helps for refactoring some parts. But if you have to change a larger feature and you will find yourself go through multiple tests and methods with an axe. The feeling of "well testedness" evaporates fast.

So, what do I suggest? Nothing really, I'm just observing. If you want well tested code, you do have to cut things into little pieces. Sometimes people overdo it, and then instead of an if-else or case-statement you get a constructor class that spits out various other classes: The if-statement is still there, it's just hidden inside one or more layers of classes. There are moments when a single run of statements with a well presented, compact decision tree of if-statements gives a lot of fresh breath when reading through things.

In coding there is always some amount of "trying to think ahead" involved, a lot of it around which part of the code will be easily adaptable. If our factory class needs to grow another option of what to spit out, that's easy. But if some assumption or constant is hidden somewhere out of the way of the "main decisions", changing this can be a pain. So your "factory" can spit out all kind of vehicles, but somewhere you assume that all vehicles have 4 wheels... you just might need to overhaul a lot of little dolls if you want to start making motorbikes too.

(This is a blog post dated 2014-09-30 18:28:00+01:00 from my old blog. See What happened to the old blog)