Тёмный

How To Implement Domain-Driven Design (DDD) in Go 

ProgrammingPercy
Подписаться 4,6 тыс.
Просмотров 37 тыс.
50% 1

The easy way of learning how to use DDD in a Go application
In this video we will learn about the different components in DDD are.
We will cover the following topics
* What Domain Driven Design is
* Domain, Model, Obiquitous Language and Sub Domains
* Aggregates
* Repositories and the Repository Pattern
* Factories to Encapsulate Complex Logic
* Services & SubServices
We will build an online tavern to learn the aspects of DDD and go through each aspect at a time.
If you want to read about this video you can find the article on my blog.
programmingpercy.tech/blog/ho...
You can find the second part of this series at
• How To Structure Domai...
00:00 Introduction
02:03 Why this video
04:22 What Is Domain Driven Design (DDD)
05:48 The Journey Of Dante (Domain Modelling Session)
09:02 Entity and ValueObject
15:43 Aggregates
29:23 Repository Pattern
51:46 Services & Configuration Patterns & More Repositories
01:31:29 Tavern Service & SubServices
01:42:14 Adding MongoDB Repository
01:55:08 Ending
Beach by MBB | / mbbofficial
Music promoted by www.free-stock-music.com
Creative Commons Attribution-ShareAlike 3.0 Unported
creativecommons.org/licenses/...

Наука

Опубликовано:

 

26 июн 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 72   
@annusingh4694
@annusingh4694 Год назад
One thing which I like very much in your teaching style is that you 'speak' your thought process, even write comments sometimes to show what you are going to implement next. This enables this video to be viewed as a guiding excercise, one can pause it at the right time, execute the solution themselves and play again to see how you did it. Thank you.
@programmingpercy
@programmingpercy Год назад
Thank you for reaching out! I am really glad you enjoy my teaching! I am happy to hear you say that you enjoy the thought process, I do try to cover those things because I often find the idea or logic behind the code to be very useful when learning. Atleast for myself, I learn faster and remember it longer when I understand the WHY and not only the HOW. Your comment made my day! Best of luck to you out there, and smash them keyboard keys!
@holgerm420
@holgerm420 Год назад
I am just 1h into the video and I'm in awe at how good of a lecturer you are. One does not often find this quality in a person. Keep up the good work!
@holgerm420
@holgerm420 Год назад
So, first of all, thank you for this lecture. I really enjoyed it and learned a lot, as I struggled to get the bigger picture of DDD - until now!
@programmingpercy
@programmingpercy Год назад
Thank you very much for saying those kind words, it warms my heart to hear! I am super happy you enjoyed it
@programmingpercy
@programmingpercy Год назад
This as actually a good idea, I will start working on a Hexagonal Tavern tutorial! Give me some time though, switching jobs next month and with Xmas and New years it's gonna be a few weeks! I would say that your assumption is correct if this was implemented in a Hexagonal design. Again, there are many flavors of doing this out there, but I'd say the services etc would be used in the adapters etc. I couldn't say right of the bat how I'd structure it, but I'll make sure to create a Hexagonal Tavern that is controlled as a CLI! Thank you for providing an interesting idea
@AlokTripathi
@AlokTripathi Год назад
Better than a lot of courses and tutorials! This is super helpful who wants to learn design pattern with practical usecase! Thanks for the effort Percy!
@stusrambles
@stusrambles Год назад
This is the best video I've seen on DDD with go. Thankyou!
@cole.maxwell
@cole.maxwell 8 месяцев назад
This was SO good, thank you! You have help put a bunch of design patterns together for me.
@kevinyu9934
@kevinyu9934 Год назад
Thanks for sharing this. It literally elevates my unstanding and usage of Golang to another level. 😄
@vmpartner
@vmpartner Год назад
Amazing. This is exactly what i'm looking for. Greate video, super clear, thank you!
@Tay74514
@Tay74514 Год назад
Thank you for making these tutorials!!
@programmingpercy
@programmingpercy Год назад
Glad you enjoyed!
@acronproject
@acronproject 7 месяцев назад
Thanks for this Mr.Percy
@adhiana848
@adhiana848 Год назад
Thank you for this Great Content!!
@vantoantran2637
@vantoantran2637 Год назад
You're amazing Percy, keep going!
@programmingpercy
@programmingpercy Год назад
Thank you!
@rodrigobaliza
@rodrigobaliza Год назад
great material, thanks a lot for your time!
@programmingpercy
@programmingpercy Год назад
You're welcome
@tartabullroberto
@tartabullroberto 5 месяцев назад
Nice course, very helpful, thanks
@Souljacker7
@Souljacker7 11 месяцев назад
Awesome, we need a FULL COURSE!
@_mansoor
@_mansoor Год назад
Awesome Percy, wow you are a wonderful lecturer!!! Great Content by the way... Enjoyed & Learned a Lot. Thank you
@programmingpercy
@programmingpercy Год назад
Thank you for the kind words, encourages me
@maydersonmello
@maydersonmello Год назад
What amazing content, it was great to see all this working together in a more real example, great patterns too, it would be amazing if you could later bring more content about this, maybe implementing it in a Rest API, thank you very much!
@programmingpercy
@programmingpercy Год назад
Thanks for your kind words!
@mi_losz
@mi_losz Год назад
Great materials Percy! 🙂
@programmingpercy
@programmingpercy Год назад
Thanks Milosz!
@viktorkrepak
@viktorkrepak 3 месяца назад
thanks a lot for such a wonderful video! a lot of useful information, right now we're going to improve our backend architecture (along with migration from Python to Go) and I'm looking for different approaches and experience and feel like you video might help us a lot to build a new architecture.
@pratyushbarikdev
@pratyushbarikdev Год назад
Wonderful. Thanks for the video. The issue I am facing is about cross-cutting concerns like logging and tracing. Not sure whether I am doing the right structuring or not with them. Bought the blue book. Let's see if it can help with those.
@ericzorn3735
@ericzorn3735 11 месяцев назад
This was an amazing DDD tutorial. Just one funny thing was the spelling of peanuts as “peenuts” in your unit tests 😂.
@programmingpercy
@programmingpercy 8 месяцев назад
Special kind of nuts, and thanks!
@user-oq2vq9co7e
@user-oq2vq9co7e 3 месяца назад
Sir make a complete series on E-Commerce.
@fprotimaru1944
@fprotimaru1944 Год назад
you saved my life
@programmingpercy
@programmingpercy Год назад
Thank you, I think saving your life is a bit exaggerated, but I am happy to hear this helped you!
@jerrysumendap2862
@jerrysumendap2862 9 месяцев назад
Thank you for the great video and lecture. It is really amazing, I have learned a lot from you. Anyway, do you mind also to share how to handle transactional is repository pattern and DDD perspective? Thanks again
@anshdharia585
@anshdharia585 Год назад
Hello from Singapore!! Thanks for the video, it is very insightful. You mentioned in the video that this directory structure is not recommended for production use cases. Would be good if you could talk more about production.
@programmingpercy
@programmingpercy Год назад
There is a whole video about that in the second part!
@wobble_cat
@wobble_cat Год назад
Transaction Value Object be like: Am I a joke for you?
@danielguldbergaaes6432
@danielguldbergaaes6432 2 месяца назад
Such a great video, one thing I noticed is that you some times do "package _test" and "package " for the test files, is there a reason to add or omit the suffix _test ?
@dranon0o
@dranon0o Год назад
I watched the entire video and the next one but I'm curious on what's the semantic related on how do you integrate: - an websocket/http server for having api access to a Service: is there a term in that DDD? is the way we manage repository can fit the case? - workers that process data from external sources to be mutated/transformed into our aggregate struct: the DDD show how to manage your own data but what about externals? what about long term processes? - utilities that allow you to perform meta programming like reflection on a struct to output data: does DDD is ideal for libraries that does that type of work? I have so much questions - can we do a reference between two aggregates?: for example we could have entities (temperature, coordinates, etc..) linked to an aggregate (planet) which belong to another aggregate (system) which also belong to another aggregate (galaxy). Great video btw, very instructive!
@programmingpercy
@programmingpercy 4 месяца назад
Thank you for watching! And good questions. 1. Well, I would say that the API is the Service. 2. I am not sure I follow the question really 3. I think DDD Fits this approach also, the meta programming is part of the logic inside a Domain, its just a way of processing logic, wouldnt matter if its regular programming or meta programming. 4. Yes, you can!
@303pix
@303pix Год назад
i'm watching it and i wanna say thanks in advance: clear and simple. But i'm asking myself in Repository Pattern chapter (about 36:00 - 40:00) why checking if person or customers map exist when you get this aggregate by factory method that assure properly init of this entities?
@programmingpercy
@programmingpercy Год назад
Good question! Extra safety and habbit I guess. The factory does prevent it, but somebody can skip using the factory etc. Not a strong reason, but I think that was why I added it.
@stasjurgensons7008
@stasjurgensons7008 Месяц назад
@programmingpercy Aren't your customer and product domains creating separate connections to the same db ? (can be seen around 1:50:00)
@tanteng1031
@tanteng1031 10 месяцев назад
Should the aggregate directory be in the domain directory?
@Augustine_354
@Augustine_354 4 месяца назад
What about generated code (like oapi-codegen)? Then my whole openapi spec is generated into one file. How one should deal with it?
@RohitKumar-fg1qv
@RohitKumar-fg1qv Месяц назад
shouldn't the products field in the aggregate.Customer struct just be []uuid instead of []*entity.Item?
@ilkerkaanadiguzel
@ilkerkaanadiguzel Год назад
i'm currently at the creating CustomerRepository and I see you don't use pointers when returning aggregate.Customer or accepting it as arguments, the struct could have a lot of data, like a lot of transactions and products, why didn't you use pointer here? How do you decide when or where to use pointers in go?
@programmingpercy
@programmingpercy Год назад
The base rule is to use pointer whenever you expect the function or the code that accepts the return value to modify the values. Since in this case we don't modify the data, no need for a pointer. When I code in Go I often overuse pointers since I want to have an easy time to Nil check though. But I've noticed that in large code bases pointers are also sometimes confusing, values changing a little bit of everywhere etc. So in this case I decided to go for the Non Pointer. True, if the structs are very big passing a pointer can have the added feature of performance gains due to avoiding copies. Though with all in mind, I do like the standard rule, is values expected to be modified, if not, regular copy, otherwise pointer. Makes the code very easy to understand.
@badhabit6140
@badhabit6140 4 месяца назад
I'm a bit late to the party, but just finished the vid and had a question about the config pattern you used to hook up the repositories to the services. with that implementation, wouldn't you need to specify the repositories on EVERY implementation of a service? wouldn't it be better to call those configs in the init of a service to avoid having to change the config in every place that you use that service?
@programmingpercy
@programmingpercy 4 месяца назад
That would be possible. I'd rather use a constructor func to initialize it and manage it that way though, I am opposed to Init functions for most usecases. But you can narrow it down with a constructor func that uses some Default repositories and configs. Init funcs have their place but I find it seldom a good approach. Init functions are also great at causing unexpected bugs and frustation in my experience
@badhabit6140
@badhabit6140 4 месяца назад
@@programmingpercy I like the default repositories approach. My concern was mostly around larger codebases where a service is used in a lot of places. If you need to change the repository, you’ll need to update all those areas where the service is being used, which defeats the point of having the config approach to begin with as it’ll be a nightmare to update all those instances.
@alonsob4069
@alonsob4069 Год назад
Hi, what if you need to update multiple orders of an user in a single transaction? the steps would be: begin tx, getUser, updateOrders, end tx but due to repositories we can't not start a lets say, postgres/mysql transaction. How can we do this in case we need a transaction through multiple repositores?
@programmingpercy
@programmingpercy Год назад
Good question Alonso! One thing that I don't show here which I commonly do is to pass in a Database conn in the Repository Factory Func. NewMysqlUserDB(db *db.Conn) Etc, that allows me to reuse the same connection if I have multiple Databases which are the same and I need to limit the amount of connections. That Db Conn can then be stored in the Repository struct and used for creating a TX
@programmingpercy
@programmingpercy Год назад
Just realized that doesn't help you. You could pass in a Ctx and use the same Root CTX between the repositories and maybe Pass the TX through there, but I've never been a fan of that myself. Either the domain scope should be altered if they have such an Relation. Another option could be to have the accept an TX of course, Pass in the TX in both Funcs simply and close it afterwards. That would be the most simple solution. It would break coupling since it would assume both repositories uses the same db engine I suppose. If there is such a coupling and needs to be done that way, I'd say creating the TX I'n a service which holds both repositories and pass the TX in the Funcs from the service, and then end tx in service is the most clean solution.
@mohamadmirmohamadi1215
@mohamadmirmohamadi1215 10 месяцев назад
How do you handle cycle dependency when some services calling each other mutually?
@programmingpercy
@programmingpercy 4 месяца назад
Cycle dependency was an issue at first for me in Go, but after a few months of go I stopped seeing that issue, its about a mindset. Services can be inside the same package, its the domains that should be separated and a Domain should preferably never need to import another domain
@yoashbentulila8638
@yoashbentulila8638 10 месяцев назад
why wouldn't you use a package for entities? and what would you do instead?
@programmingpercy
@programmingpercy 4 месяца назад
I am just not very happy with the Globally shared Entities approach. But I do it in some projects when an entity is shared across the entire scope of the project. I do like having entities as part of their respective Domain. If I am building a GitHub Domain, then the github related entities are found in that domain
@Flascoo
@Flascoo Год назад
Do you have a repo with this code?
@programmingpercy
@programmingpercy Год назад
Yes sir! The first video code can be found here: github.com/percybolmer/ddd-go Second video is focused on cleaning the structure up, since the first video uses a weird setup to emphasize the theory and ideas. That code is in a second brach in the same repo github.com/percybolmer/ddd-go/tree/clean-architecture I hope this helps you
@Flascoo
@Flascoo Год назад
@@programmingpercy Thanks!
@djgpp933
@djgpp933 8 месяцев назад
Cool explanation, how ever this is just crud, where will you add busines rules for instance, imagine there is a rule to not allow orders after 3pm or only allow to save only one beer by order I mean business rules not crud rules.. where will add those?
@programmingpercy
@programmingpercy 8 месяцев назад
Good question! I'd add that in the Service or the Aggregates.
@klamberext
@klamberext 8 месяцев назад
Peenuts.
@programmingpercy
@programmingpercy 8 месяцев назад
Haha yeah, my bad xD Also, a tip: don't ever order peenuts in a bar, you might get a real chocker
@arvee-4699
@arvee-4699 Год назад
do you live in paderborn or like all german houses look the same lol XD
@programmingpercy
@programmingpercy Год назад
Haha, sorry, I don't even love in Germany! I am living in Sweden, so pretty close though.
@jeromelanteri321
@jeromelanteri321 8 месяцев назад
interesting. At the very first start point, you exposed an idea about language use case to call same things differently with example by analogy as client to be also a drinker. By the facts, they are not the same thining of the same people as long as people doesn't react the same in different context. Ok, it is the same person id, but not the same idea of this person now. The bankster is looking for his money as a client, but the wine manufactor is looking at him as someone that will love his wine (the underground target is not the same, and because of that, depend of who is controlled the activity, the experience of the people will not be the same with a bankster and a wine manufactor). So, even if i do understand your point to teach domain driven design at the very first point, we can not delete that most of the time, people forget that they has been called differently because the target is very different and that is the power of a language to use the correct appelation depend of: "the context" (so, it is the school role to make student understand that crucial point that make a big difference between a dumb tool's guy society and an intelligent society). The context is the one than help to define the correct word to use to define a subject (it is lexicaly correct to understand this about language). Also, there is some "generic", that can embed all of them. For example, a client is a drinker or what ever that can paid for something, but all of them are humans (i think animals will not be accepted to drink or to paid for the drink too). It is all about to understand layer up to abstraction that exist due to context and motivated target. Let's said that this way we name things would also influence our own mind thinking the way we are thinking this topic about. And that is all about humans relationship and project orientation is. What i said is that... who is the boss ? Who is the one that should define the orientation of the project if not the owner of the project ? Is it the man that borrow the monnaie or is it the man that know to do the job and his the owner because of that ? Let me tell you an example that describe our low level society it is becoming right now because of genereic inplace of anything without conscience (because to not understand that point): More and more, now, in hospital, due to free international crazy market , people injured or seek are becoming: clients. And that is why they are not happy in this hospital who has no human skills as target at the very frst place. Peoople injured are no more happy due to the very low quality of treatment, and employed people are also not happy due to the treatment they have from the hospital that is becoming an other room for businessmen, instead to still be some valuable technicians, they become diplpomate personal, with lower and lower skills by the fact, with more an dmore pressure about time to treat a... client (or at least, a society of dumb that see only generic or there own business word to be the absolute priority, out of any cultural context, out of any politic context, out of any real life context and then, because of that, out of any valuable morality context). You can not make an adapter/wrapper between business and medecine or professional . Yeah... you can do it, but it is useless from the first start point to the end one.
@programmingpercy
@programmingpercy 4 месяца назад
First off, Thank you for watching and taking the time to discuss this. And I think that we shouldn't overthink this too much. It's all about finding common ground and a good enough abstraction that fits the model of the business scope. Although you have an interesting point.
@chenjaike950
@chenjaike950 Год назад
may be also need mutex to read map? here's chat gpt's example package main import ( "sync" ) type SafeMap struct { sync.Mutex Map map[string]string } func main() { // create a new safe map safeMap := SafeMap{Map: make(map[string]string)} // use the map in multiple goroutines go safeMap.Write("key1", "value1") go safeMap.Write("key2", "value2") go safeMap.Read("key1") go safeMap.Read("key2") } func (sm *SafeMap) Write(key string, value string) { sm.Lock() defer sm.Unlock() sm.Map[key] = value } func (sm *SafeMap) Read(key string) string { sm.Lock() defer sm.Unlock() return sm.Map[key] }
Далее
How To Structure Domain Driven Design (DDD) In Go
27:36
ВСЕ СЕКРЕТЫ КОТА В ВР ( I Am Cat VR )
22:46
What is DDD - Eric Evans - DDD Europe 2019
57:06
Просмотров 254 тыс.
8 Design Patterns | Prime Reacts
22:10
Просмотров 387 тыс.
Exciting Go Update - v1.22 Change Log With Examples
27:57
ШБР 2023 - Архитектура кода (Go)
59:25
22. Новый раутер в Go 1.22
39:17
Развод с OZON - ноутбук за 2875₽
17:48
YOTAPHONE 2 - СПУСТЯ 10 ЛЕТ
15:13
Просмотров 42 тыс.
#miniphone
0:16
Просмотров 3,6 млн