Hah, no, they're not. Every production app is read many, many times by several different developers, mostly to search for bugs. Reading across adapters, services, and interfaces make that much harder. Especially, if the architectural pattern was implemented slightly differently every time by various authors.
Abstraction always comes with a price. Often, it is well worth to pay (or we would still code everything in C or assembly), but sometimes it's just a waste.
I think people here are devaluing the "kind of approach" taken in these over-abstracted-architectures. The snippets of "improved" code in TFA have a lot of new line-noise, a lot of boilerplate and half-a-dozen "new" pieces of terminology, all in the quest to essentially separate IO and core logic.
There's plenty of ways to perform this separation, many of them don't require replicating half the design-patterns from C# tutorial. I'm pretty partial to "functional-core, imperative-shell", I think that it achieves all the same advantages, with none of the new concepts, and far less line noise.
There really are very different perspectives on what makes code easy to manage, and interfaces (especially ones used only for a single class) are a sure-fire way for me to make code unmanageable. But java enterprise coders disagree. That can clash hard.
Not sure java is bad for indirections, java is bad for boilerplate and lack of defaults, imho. But I usually don't use frameworks/stlib directly, so I create my own boilerplate that is reusable
So I'm not talking about having one or two sensible interfaces as a contract, but codebases where every class has at least one interface, for "decoupling". Pure hell.
Concrete example from work today - we have a trading application and there are many paths that lead to alerts of some kind. Alerts are usually raised inline with any business logic (as should be - they intrinsically coupled). Alerts however can be delivered differently - via SMS, other messaging systems and/or log messages. The different places where the alerts need to be generated do not _need_ to know how the alert is going to be physically delivered to its destination - they just need to generate it. Without an interface (or at least a type alias for a function) - it would make being able to say e.g. this alert is a direct phone message vs. a chat message in some channel because of the type it is - much harder.
In the system I worked on the shortcut did not work - too many options or some consequence of the dependency system, additional layers of indirection.
In real life, you just can't have it both ways. There's always a trade off. If the trade makes sense go for it I say, but I think people aren't always honest (to me or themselves) about the exact trade they are making.