Lasagna code - too many layers?
I read this tweet:
"The object-oriented version of spaghetti code is, of course, 'lasagna code'. Too many layers." - Roberto Waltman— Programming Wisdom (@CodeWisdom) February 24, 2018
Jokes taken as advice
It's not the first time I'd heard of this quote. Somehow it annoys me, not just this one joke, but many jokes like this one. I know I should be laughing, but I'm always worried about jokes like this going to be interpreted as advice, in its most extreme form. E.g. the advice distilled from this tweet could be: "Layers? Don't go there. Before you know it, you have lasagna code..."
It's the same for every lame microservice joke out there; I feel most of those jokes cause people to reject any idea (no matter how good) related to splitting a monolith, using a service architecture (an architecture with services, not necessarily micro ones), etc. Like all things, it won't always be a good choice, but it won't be never a good choice either.
Actually, I think it would be awesome if people would more often consider the option to use some kind of event-driven service-based architecture. Just like I think it would be awesome if people would write more lasagna code, or layered code. Most attempts at layering fail horribly, just like many (most?) attempts at building services fail horribly. Why is that? Because mostly, we have no idea what we're doing. We do know our favorite frameworks by heart. Every configuration option, every little validation constraint, every command-line tool. But we don't know architecture that well.
As I've pointed out before, layers are indeed a great architectural tool for structuring your code. I won't repeat everything here. I just wanted to discuss the concept of a layer a bit more, because this tweet and my own response to it - "Actually, I've never encountered such a project." - received some interesting reactions, for example:
You haven’t? I have some to show you :D. Too many abstractions and services.— Jelrik van Hal (@jelrikvh) February 25, 2018
I think I have, but it's more about the layers of the call stacks at runtime than how the code is organised. Service A made up of X layers gets injected into service B, which is already made up of Z layers...— Dave Marshall (@davedevelopment) February 25, 2018
Indirection, not layering
This is actually what I was hinting at: layers, when applied successfully (I'll talk about what I mean by that), are a great thing for a code base. However, most attempts at layering actually result in (not layering, but) indirection. If you'd step-debug through unsuccessfully layered code, you'll taking many steps before you get to the clue of the joke: that all we're doing is bringing out some data, and putting it back in. The complicated steps hiding this simple truth, are the steps of a weird dance between controllers, action helpers, services, tables, data objects and mappers. A lot of indirection, due to mixing in infrastructural concerns at al levels, and often clumsy usage of the programming language.
Trying to trace the workings of this kind of code may feel like you're wading through sticky layers of lasagna. Or maybe, it feels more like peeling of layers of an onion. However, it doesn't mean we should get rid of the concept of a "layer". We only need to realize that what we're looking at really aren't layers.
Successful layering: define the rules
I think it only makes sense. We're trying to deal with the code we're looking at, trying to make it manageable. It's impossible to keep everything in our head at once. We try to follow rules like "skinny controllers", so we push code out of them. We want to prevent historical failures like having
mysql_query() calls all over the place, we don't want to mix PHP with html, and then this indirection ("too many layers" a.k.a. "unsuccessful layering") is what happens.
In my experience, successful layering can be achiev
Truncated by Planet PHP, read more at the original (another 2093 bytes)