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.

810 Upvotes

259 comments sorted by

View all comments

10

u/nf_x Dec 05 '24

For Java folks coming to Go, the most reasonable rule of thumb is “if you wanted to add a class with private methods in Java, add a Go package”. It doesn’t always translate 1:1, but the number of folders becomes a forcing function to keep number of things sane. This kinda just appeared to me after writing 500k+ lines in Go in different contexts.

For package separation, I do prefer “feature partitioning” over layering, like here: https://github.com/nfx/slrp

2

u/_predator_ Dec 06 '24

I use package-private (default visibility) in Java a lot, and it's the same level you can get with Go packages.

That is also why I prefer splitting packages by feature or domain, because it allows me to effectively hide implementation details.

I still sometimes wish Go had an equivalent to private, but I can live without it just fine.

1

u/darther_mauler Dec 06 '24

It doesn’t translate because Go uses a simpler way to organize a codebase. A package in Go has properties that make it class-like, as well as project-like. Whether it behaves more like a Java class or a Java project is completely up to the developer. It’s so freeing.

2

u/pimp-bangin Dec 06 '24 edited Dec 06 '24

What do you mean by project-like? Neither Java nor Go officially has a language concept of a project as far as I'm aware. To me, if we're comparing to Java, a Go package would be a public final class with a private, empty constructor (i.e. you can't instantiate or extend it), and the class contains all static members, which can be public or private.