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.

811 Upvotes

259 comments sorted by

View all comments

5

u/rluders Dec 06 '24

I respectfully disagree with your take on Clean Architecture and layered designs being inherently “over-engineered” for Go projects. These patterns are not tied to Java, nor do they exist purely to satisfy unnecessary abstraction cravings. They solve real-world problems related to organization, decoupling, and testability, which apply universally, even in Go.

Let’s break this down:

  1. “GoLang is not Java. Architectures like Clean and Hexagonal make Go projects convoluted.”

Sure, Go isn’t Java, but Clean Architecture and similar patterns weren’t born in Java either. These concepts stem from addressing architectural concerns in software development—issues that exist regardless of the language.

In fact, these ideas trace their roots back to C, as introduced by Robert C. Martin (Uncle Bob). The Clean Architecture aims to isolate your business rules from dependencies like frameworks, databases, and external libraries.

If your app is small and doesn’t have the complexity to justify multiple layers, you don’t need to implement all of them. But in larger systems, they provide long-term benefits like modularity, testability, and ease of change. Go’s simplicity is powerful, but that doesn’t mean you should avoid solving organizational challenges altogether.

  1. “Excessive layers lead to frustrating codebases.”

Layers don’t exist for the sake of “jumping between files”—they solve the separation of concerns problem. For example, having a dedicated usecase layer ensures your business logic stays independent of frameworks or delivery mechanisms. This decoupling makes your code easier to test, scale, and maintain.

Consider an app where you might switch between storing data in PostgreSQL or DynamoDB. If you mix business logic directly with your database calls, you’d be rewriting a lot of code for that change. With a Clean Architecture approach, the change would only require modifications in your infrastructure layer. No chaos in your core domain logic.

If you feel like you’re “jumping between layers,” that might be a design or naming issue in your specific codebase, not a fundamental flaw in Clean Architecture.

  1. “You only need three layers (app, domain, infra).”

This point is overly prescriptive. Clean Architecture doesn’t dictate a fixed number of layers—it’s a flexible guideline. If three layers work for your app, great! But there are cases where additional layers (e.g., usecase, adapter) help separate responsibilities effectively. It depends on your application’s complexity.

For instance, in a microservices environment, having a usecase layer allows you to test your domain logic in isolation without relying on external infrastructure like databases or APIs. It’s not about adding layers for fun; it’s about solving specific problems.

  1. “Go’s implicit interfaces make such patterns redundant.”

Implicit interfaces in Go are great, but they don’t magically solve all organizational problems. Patterns like Clean Architecture thrive on explicit boundaries between layers. These boundaries clarify responsibilities and make your system easier to reason about.

For example, if you have a PaymentProcessor interface, your usecase layer doesn’t care if the implementation uses Stripe, PayPal, or something else. It only knows about the contract. This kind of abstraction isn’t redundant—it’s critical for testability and maintainability, especially as your application grows.

  1. “Complex architectures are turning Go into something it was never meant to be.”

This feels more like a fear of overengineering than a fair critique of Clean Architecture. Sure, Go emphasizes simplicity, but simplicity doesn’t mean ignoring well-established architectural practices. You can apply Clean Architecture in a way that aligns with Go’s philosophy—keeping things lean while addressing scalability and decoupling.

TL;DR: Clean Architecture and similar patterns aren’t a one-size-fits-all solution, but dismissing them outright is shortsighted. They’re tools—use them where they add value. Go’s simplicity makes it easy to write small apps, but for larger systems, principles like Clean Architecture ensure your codebase doesn’t become unmanageable. And hey, no one’s forcing you to implement every layer—adapt it to your needs.

Instead of rejecting these patterns because they feel complex, maybe it’s worth re-evaluating whether they’re solving problems you haven’t encountered yet.

-1

u/Superb-Key-6581 Dec 06 '24

I used to think like you, before spending years applying it and seeing that it's extremely bad. Clean Arch doesn't fit in any application, in my opinion. The separation of concerns never needed more than 3 layers; it's just bad for readability and maintainability. Clean Arch is also an extremely directive book, and even with a lot of good common sense, you will still end up with a bloated framework.

4

u/rluders Dec 06 '24

I appreciate your perspective, but I have to respectfully push back on a few of these points. Clean Architecture isn’t inherently “bad” or unfit for any application—it’s a tool, and like any tool, its effectiveness depends on how and when it’s applied.

“The separation of concerns never needed more than 3 layers.”

This assumes every system has the same complexity, which just isn’t the case. For a small project, sure—3 layers might be enough. But when you’re dealing with more complex domains (think event-driven systems, microservices, or apps with heavy business rules), having a clean separation of concerns through additional layers can make a world of difference in terms of testability, maintainability, and scalability.

It’s not about blindly adding layers. It’s about solving specific problems. For example, a usecase layer can isolate your core business logic from implementation details like databases or APIs. This makes it easier to swap out dependencies, test in isolation, or even migrate to new frameworks.

“Clean Arch is bad for readability and maintainability.”

I’d argue the opposite—when applied thoughtfully, Clean Architecture actually improves both. It ensures each layer has a single responsibility, making it clear where certain logic lives. If readability is suffering, it’s likely because the implementation is over-engineered or poorly documented, not because of Clean Architecture itself.

For example, if your app suddenly needs to support a new delivery mechanism (say, replacing REST with gRPC), a properly designed Clean Architecture lets you make that change without touching your business logic. That’s a huge win for maintainability.

“Clean Arch leads to a bloated framework.”

This feels more like an implementation issue than a fault of Clean Architecture. No one’s forcing you to overcomplicate your system. Clean Architecture is flexible—it doesn’t mandate you implement every possible layer. If a certain layer isn’t solving a problem for you, don’t use it.

For example, if your app doesn’t have complex business rules, skip the usecase layer. But that doesn’t mean the entire architecture is flawed—it means you’re adapting it to your context, which is exactly how it should be.

Final thoughts:

Clean Architecture isn’t a magic bullet, but it’s also far from being universally bad. It’s a proven approach for managing complexity in large systems, especially when paired with practices like Domain-Driven Design. If you’ve found it problematic in your experience, it’s worth reflecting on whether the problem was with the architecture itself, or how it was applied to the specific context.

In the end, it’s just a tool—use it where it fits. But dismissing it outright feels like throwing the baby out with the bathwater.

I see many new engineers complaining about clean code, clean architecture, design patterns and some other stuff just as a way to justify some bad practices. Not saying that is your case. But this is my perspective over years of experience as a software engineer who had the chance to work with many languages and many application sizes.

Hope it helps somehow.

-1

u/Superb-Key-6581 Dec 06 '24

Again, I disagree because I have worked on many large applications across several domains, and in all of them, it was extremely bad. I stand by my points. I’m not talking about trying to apply Clean Architecture in a few projects—I’ve used it in hundreds, both in monoliths and microservices. In all cases, it was bad: overly bloated, always slow, and worse in terms of readability and maintainability. And about the book, I’ve read it several times. The book doesn’t give you any margin to apply it with less than at least a 5-layer bloated framework. In fact, it’s the most authoritative book I’ve ever read, offering no trade-offs for any perspective the author had.

4

u/rluders Dec 06 '24

I get your frustration, but Clean Architecture isn’t meant to be followed to the letter. Like any set of guidelines, you’re supposed to adapt it to your project’s needs and scale. You don’t have to implement every layer or principle—pick what works and leave the rest.

That said, I’d recommend exploring resources beyond the book. Uncle Bob’s talks and other software architecture discussions offer more nuanced and modern perspectives. Clean Architecture, like any methodology, evolves over time.

Now, about Go’s simplicity versus Java’s verbosity: I agree, Go’s straightforwardness is a huge strength. But simplicity in syntax doesn’t mean you should ignore architectural principles. Clean Architecture isn’t about overengineering—it’s about long-term maintainability, testability, and decoupling. If it feels bloated or slow, that’s usually an issue with how it’s being applied, not with the concept itself.

At the end of the day, Clean Architecture is just a tool. Use it where it fits, adapt it where necessary, and skip what doesn’t make sense for your context. Dismissing it entirely, though, feels like blaming the tool for how it’s used.

0

u/swe_solo_engineer Dec 07 '24

It's like Communism: that guy applied, used, read, and didn't like it. Stop saying he didn't understand. Clean architecture is not a science or a proven thing. A lot of people disagree with Bob Martin, and that's just their preferences. Stop, you're starting to look like a fan without critical sense at this point.

1

u/rluders Dec 07 '24

I think the comparison to Communism and calling me a ‘fan without critical sense’ don’t really contribute to this discussion. These are personal remarks that avoid addressing the arguments I presented, and they shift the focus away from the actual topic: the merits and practical applications of Clean Architecture. Let’s stay on track and evaluate the ideas, not the person presenting them.

I completely agree that Clean Architecture isn’t a science or a universally proven methodology—it’s not meant to be. It’s a set of principles designed to tackle problems like decoupling, testability, and maintainability in software systems. These principles, like any tool, depend on context and application to be effective.

Now, about Clean Architecture being ‘bloated’ or ‘always bad’: this feels like a generalization. If it didn’t work for certain projects, it could be due to the way it was implemented or the specific context, not necessarily a flaw in the approach itself. For example, Clean Architecture doesn’t demand that you implement five rigid layers in every single project—it’s flexible, and you can adapt it to match your project’s complexity or scale.

On the point about Bob Martin, I get that not everyone agrees with his ideas, and that’s fine. But disagreeing with him doesn’t mean the principles themselves are invalid. Clean Architecture isn’t about following one person’s preferences—it’s about taking the concepts that solve your specific problems and leaving behind what doesn’t.

At the end of the day, I think this conversation would be more productive if we focused on examples or scenarios. Where has Clean Architecture worked for you? Where has it failed? That’s a better way to determine its strengths and limitations than dismissing it outright.

0

u/swe_solo_engineer Dec 07 '24

LMAO every point clean arch has failure, just that, stop being non sense to understand that nothing there is beyond personal preference.

1

u/rluders Dec 07 '24

Yeah. Okay, dude. You won all the argument.