bxcodec / go-clean-arch

Go (Golang) Clean Architecture based on Reading Uncle Bob's Clean Architecture
MIT License
9.06k stars 1.19k forks source link

feat: Introduce domain package #21

Closed bxcodec closed 4 years ago

bxcodec commented 5 years ago

Hello, everyone who reads this and (maybe who also used my proposed architecture in Go).

Thank you very much for the feedback that I received so far. Just to be honest, I'm very new here in the architecting software worlds. So, I'd rather call it folder structure rather than architecture. As we know, software architecture is not just a single application, but a whole business that architected into one or many applications.

Actually, for the current version in the master branch (when I made this PR), nothing wrongs. By far, this project structure solved many cases of my projects.

But, in this recent months, I try several improvements (also with looking at other people's architecture in Go), so now I decide to introduce a domain package.

In my current structure, we will find something like this:

models
├── article.go
├── author.go
└── errors.go 

article
├── delivery
│   └── http
│       ├── article_handler.go
│       └── article_test.go
├── mocks
│   ├── ArticleRepository.go
│   └── ArticleUsecase.go
├── repository //Encapsulated Implementation of Repository Interface
│   ├── mysql_article.go
│   └── mysqlarticle_test.go
├── repository.go // Repository Interface
├── usecase //Encapsulated Implementation of Usecase Interface
│   ├── articleucase_test.go
│   └── artilce_ucase.go
└── usecase.go // Usecase Interface.

So there are will be many packaged module like author, article that contains the implementation and also the contract ArticleUsecase, ArticleRepository, AuthorRepository

So, just out of curiosity, I tried a new improvement that proposed by Ben Johnson here: https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1 the domain package. But instead of to move it into the root project, I'd rather move it into a single domain, just for the sake consistency with my previous layout that using package models

So in my previous layout, I used models and now I renamed it to domain then move all the interface contract (Usecase and Repository) into this domain package.

So it will be more like this:

domain
├── mocks
│   ├── ArticleRepository.go
│   ├── AuthorRepository.go
│   └── ArticleUsecase.go
├── article.go
├── author.go
└── errors.go 

article
├── delivery
│   └── http
│       ├── article_handler.go
│       └── article_test.go
├── repository //Encapsulated Implementation of Repository Interface
│   └── mysql
│       ├── mysql_article.go
│       └── mysqlarticle_test.go
└── usecase //Encapsulated Implementation of Usecase Interface
    ├── articleucase_test.go
    └── artilce_ucase.go

I don't know yet, is this new layout better than the current layout I used. But, I'll try to use this new layout for my projects. If anything happens, then, this PR will be closed. But if it's good and more comfortable for the developer to use it, then I'll merge this to the branch master. :D


Anyway, if you're a Golang Engineer too, I'd like to hear your opinion about this new proposed layout :D

sananguliyev commented 5 years ago

I think this structure is better in terms of the DDD.

jcorry commented 5 years ago

I'd love to see discussion on this from Go architects more experienced than myself.

bxcodec commented 5 years ago

Hi @jojoarianto,

In this PR there are many changes related to pointer just for safer in memory allocation. There is an explanation about this here https://segment.com/blog/allocation-efficiency-in-high-performance-go-services/

So to summarize, I think, if we really don't need a pointer, we better to avoid it. It's just a part of the optimization in Golang. If you're not really concern about memory allocation, it's okay to ignore this.

AlexGrs commented 4 years ago

hey ! Curious to know if you did continue with this domain approach or if you revert back to using the previous one (models at the root) with use cases in each sub-packages.

bxcodec commented 4 years ago

Hi @AlexGrs , for microservice I use this.

But for the monolith, I use the previous one, because Monolith will look messier if we organized like this. I mean the contracts all in one place