betabug... Sascha Welter

home english | home deutsch | Site Map | Sascha | Kontakt | Pro | Weblog | Wiki

30 September 2014

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.

Posted by betabug at 18:28 | Comments (1) | Trackbacks (0)
ch athens
Life in Athens (Greece) for a foreigner from the other side of the mountains. And with an interest in digital life and the feeling of change in a big city. Multilingual English - German - Greek.
Main blog page
Recent Entries
Best of
Some of the most sought after posts, judging from access logs and search engine queries.

Apple & Macintosh:
Security & Privacy:
Misc technical:
Athens for tourists and visitors:
Life in general:
<< Splish splash I was taking a vacation | Main | Mini Glas-Container >>
Comments
Re: Matryoshka Code

"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."

That journey can be a bit easier if you add some good comments when you first write those little classes. Either docstrings (if we are talking about python code) or comments here and there mixed with the code.

Also, for certain cases, there are some tools out there that "inspect" your code, generating graphviz/dot/png charts with diagrams and info about classes, models, relations/inheritance between them, etc. This is also helpful if you are trying to get a grip on something somebody else wrote.

Only example that come to mind right now is this, django specific, tool: http://django-extensions.readthedocs.org/en/latest/graph_models.html but for sure there are more of those out there.

Posted by: Wu at October 02,2014 08:23
Trackbacks
You can trackback to: http://betabug.ch/blogs/ch-athens/1352/tbping
There are no trackbacks.
Leave a comment