It's been that way long before agile methodology or microservices though. Complexity-for-the-sake-of-complexity EverthingHasToBeAnAbstractClass frameworks have been plaguing the software development business since at least the 1990s and I'm sure there are similar stories from the 80s and 70s.
It's hard to find a one-size-fits-all easy method for not falling into that over-engineering / over-management trap. I try to focus on simple principles to identify needless complexity:
- There is no silver bullet (see "microservices"): If the same design pattern is used to solve each and every problem there probably is something amiss.
- Less code is better.
- Favour disposable code over reusable code: Avoid the trap of premature optimisation, both in terms of performance and in terms of software architecture. Also known as "You aren't gonna need it".
- Code means communication: By writing code you’re entering a conversation with other developers, including your future self. If code isn't easily comprehensible again there's likely something wrong.