Truthfully - I wouldn't call it spaghetti code. I think of spaghetti code as way to many abstractions (AbstractEntityFactoryFactory). This code has the opposite problem - needing more abstractions - which is the easier direction to move.
Global state causes code to be spaghettified. Having worked on several code bases that qualify as spaghetti code, the hallmark trait is that the execution flow is wound back around itself many times, like noodles in a bowl of spaghetti, in a way that's not easy to trace. You may have nice abstractions or none. You may have deeply nested type hierarchies or a seemingly nice flat structure. You may be using an IoC container with neatly separated services. None of it matters, you can get spaghetti code with all of them.
Just use global state! Then you can have something where Module A depends on Module B. Now, at one point Module A calls into Module B which fires off an event that's handled in Module C that then calls back into Module A. If that event is going through a pub/sub notifier, bam, hidden global state. Good luck tracing that subtle bug down when you swapped out implementations of Module C thinking the new one explicitly filled the contract of the old one, or worse yet not realizing Module B indirectly depended on C in the first place, and that A's response to the call from C may repeat the cycle several times. Soon you realize everything depends on everything else and your tooling does you no good. That's spaghetti code, just as bad or worse than the gotos sprinkled through some ugly C code that an undergrad wrote in the 80s.
That’s sort of what I thought of. Is soon as I read a bit about having global variables at the top of every file I am mediately remembered how I used to program BASIC when I was first trying to learn it.
Spaghetti code is when procedural/functional coding goes wrong which is pretty much opposite of too much abstaction. Basically, spaghetti is what was before OOP when it went bad. At least, I did not heard people to refer to too much abstraction as spaghetti before.
For the record, this one is not that bad. It is comprehensible and pretty easy to refactor. Real spaghetti is something you have no idea what it does.
Spaghetti code by its original conception, code that uses GOTO to jump all over the program willy-nilly, mostly died with the adoption of procedural languages that eliminate or mitigate the usage of GOTO, forcing naive procedural style into something more reminiscent of straight-line code(which is generally a good practice, but still easy to deviate from with nested loops, function calls, state machines, etc.). But the general idea of "pasta code" that is hard to follow is going to stick around by any name.