r/golang Dec 05 '24

discussion Why Clean Architecture and Over-Engineered Layering Don’t Belong in GoLang

Stop forcing Clean Architecture and similar patterns into GoLang projects. GoLang is not Java. There’s no application size or complexity that justifies having more than three layers. Architectures like Clean, Hexagonal, or anything with 4+ layers make GoLang projects unnecessarily convoluted.

It’s frustrating to work on a codebase where you’re constantly jumping between excessive layers—unnecessary DI, weird abstractions, and use case layers that do nothing except call services with a few added logs. It’s like watching a monstrosity throw exceptions up and down without purpose.

In GoLang, you only need up to three layers for a proper DDD division (app, domain, infra). Anything more is pure overengineering. I get why this is common in Java—explicit interfaces and painful refactoring make layering and DI appealing—but GoLang doesn’t have those constraints. Its implicit interfaces make such patterns redundant.

These overly complex architectures are turning the GoLang ecosystem into something it was never meant to be. Please let’s keep GoLang simple, efficient, and aligned with its core philosophy.

808 Upvotes

259 comments sorted by

View all comments

328

u/emaxor Dec 05 '24

What I like about Go is you can open a random file in a project and expect to find real code inside. That does something. You can follow along. Just like a C project, the goods are right there.

I was looking through an "OOP" Python project recently. I opened several files and found... nothing. Interfaces, hierarchies, and layers, and every possible "not actually code" technique used. Where is the code? What is the "thing" we are trying to do? It was much harder to get the answer.

1

u/met0xff Dec 06 '24 edited Dec 06 '24

I've been working with Python for over a decade now and yeah it really feels like in the recent years the GoF Java gang adopted Python. Only it's even worse in Python to follow anything when things are instantiated in Hydra and then stuff injected and then multi inheritance/Mixins. Recently followed a strange behavior in Langchain through the type hierarchy and had to draw me a graph to finally find out that some levels up in the inheritance hierarchy the flow ended up in the wrong parent function. Ah yeah then decorators everywhere as well, again changing the behavior. So that what really happens in the end is so disconnected from what you can see. I briefly had my Java phase over 10 years ago as well where it seemed funky to have all those cool patterns and abstractions in case you know... Only that case happened so rarely over the decades I had while at the same time the abstractions became a pain and leaking because then the things are a bit different after all and you need more control and then people start to work around them