TubeSum ← Transcribe a video

Gordon Skinner - Hexagonal Architecture in DDD

Transcribed Jun 15, 2026 Watch on YouTube ↗
Intermediate 12 min read For: Software developers familiar with OOP and web frameworks, interested in DDD and architectural patterns.
17.2K
Views
166
Likes
0
Comments
5
Dislikes
1.0%
📊 Average

AI Summary

Gordon Skinner discusses Domain-Driven Design (DDD) and Hexagonal Architecture, using a golf application as an example. He explains key DDD concepts like entities, value objects, ubiquitous language, and bounded contexts, then shows how hexagonal architecture helps decouple the domain from external concerns.

[03:46]
Introduction to Domain-Driven Design

DDD focuses on understanding the domain (sphere of knowledge) and modeling software accordingly. Eric Evans' book 'Tackling Complexity in the Heart of Software' (2003) is the foundational text.

[05:42]
Entities vs Value Objects

Value objects (like £10 notes) are immutable and equal based on their values. Entities (like laptops) have identity and mutable state.

[08:44]
Model-Driven Design

Models represent nouns in the domain and should be simple, adhere to single responsibility, and reflect real-world concepts. They should be built collaboratively with domain experts.

[11:03]
Ubiquitous Language

Use the same language in code as in discussions with domain experts. Avoid ambiguous terms; names should reflect how non-developers talk about the domain.

[16:36]
Bounded Context

Subdivide the domain into bounded contexts where terms may have different meanings. Example: 'bunker' means different things to a club pro vs a greenkeeper.

[19:38]
Services in DDD

Services represent actions that cause state changes to entities but do not have state themselves. They should be named based on real-world needs.

[21:08]
Continuous Integration and Domain Evolution

Domains evolve; merge code quickly and often. Testing strategies (like PHPSpec) help flag unintended changes.

[22:48]
Tips for Successful DDD

Build models collaboratively, iterate, accept domain evolution, have access to domain experts, and test extensively.

[26:49]
Hexagonal Architecture Goals

Allow the application to be driven by users, programs, tests, or batch scripts, and developed in isolation from runtime devices and databases.

[31:03]
Ports and Adapters

Ports define contracts for interactions (e.g., saving data). Adapters provide concrete implementations (e.g., MySQL, Redis, file system).

[33:43]
Example: Club Repository

A repository interface defines save and find methods. Concrete adapters implement these for different storage backends.

[36:48]
Porter for UI Data

A porter handles import/export of data to/from the UI, allowing controllers to be thin and domain-agnostic.

DDD and hexagonal architecture help create maintainable, testable software by focusing on the domain and decoupling it from infrastructure concerns. The key is collaboration with domain experts and continuous communication.

Clickbait Check

90% Legit

"Title accurately reflects content: a talk on hexagonal architecture within DDD context."

Mentioned in this Video

Study Flashcards (10)

What is a value object in DDD?

easy Click to reveal answer

An immutable object whose equality is based on its values, not identity.

05:42

What is an entity in DDD?

easy Click to reveal answer

An object with a unique identity and mutable state.

05:42

What is ubiquitous language?

medium Click to reveal answer

Using the same language in code as in discussions with domain experts to avoid ambiguity.

11:03

What is a bounded context?

medium Click to reveal answer

A subdivision of the domain where terms may have different meanings.

16:36

What is the purpose of a service in DDD?

medium Click to reveal answer

To perform actions that cause state changes to entities without having state itself.

19:38

What is the goal of hexagonal architecture?

hard Click to reveal answer

To allow an application to be driven by various inputs and tested in isolation from runtime devices and databases.

26:49

What is a port in hexagonal architecture?

hard Click to reveal answer

A contract that defines how to interact with the domain (e.g., save data).

31:03

What is an adapter in hexagonal architecture?

hard Click to reveal answer

A concrete implementation of a port (e.g., MySQL adapter, file system adapter).

31:03

Why is the hexagon shape used in hexagonal architecture?

medium Click to reveal answer

To allow room to draw ports and adapters without being constrained by a one-dimensional layer diagram.

28:08

What is the key tip for successful DDD?

easy Click to reveal answer

Talk with each other; collaborate with domain experts.

24:53

💡 Key Takeaways

💡

Entities vs Value Objects

Clear, memorable analogy using £10 notes and laptops to explain core DDD concepts.

05:42
⚖️

Ubiquitous Language

Emphasizes the importance of consistent naming across code and business discussions.

11:03
💡

Bounded Context Example

Illustrates how the same term ('bunker') can have different meanings in different contexts.

16:36
⚖️

Talk with Each Other

Stresses communication as the most important takeaway for DDD success.

24:53
📊

Hexagonal Architecture Goal

Concise definition of the architecture's purpose: isolation and flexibility.

26:49

✂️ Creator Tools: Viral Hooks

AI-generated clip ideas for Shorts based on the transcript

Live demo vs. golf talk: brave or stupid?

45s

The speaker humorously claims talking about golf to PHP developers is braver than a live demo, creating immediate curiosity.

▶ Play Clip

£10 note swap: value objects explained

54s

A simple, visual demonstration with money makes the abstract concept of value objects instantly understandable and memorable.

▶ Play Clip

Laptop swap fail: entities vs. value objects

60s

The contrast between swapping £10 notes and refusing to swap laptops humorously illustrates the difference between value objects and entities.

▶ Play Clip

You're not the domain expert!

60s

The speaker challenges developers by declaring they are not domain experts, prompting self-reflection and engagement.

▶ Play Clip

Hexagon is not a hexagon?

60s

The surprising revelation that hexagonal architecture doesn't require six sides sparks curiosity and corrects a common misconception.

▶ Play Clip

[00:06] So first things first, who am I? Uh my

[00:08] name is Gordon. Uh at the moment I work

[00:10] for a startup called Re channel. Been

[00:12] doing that for a few months. Previously

[00:14] I was a team lead at Enva. Before that I

[00:18] was a senior developer at Moo and before

[00:19] that I did some net. Um you can contact

[00:23] me on these two um places. I'm generally

[00:27] not good at responding but give me a

[00:29] prod. I'll get back to you. Um, but

[00:31] generally honestly, if if you don't get

[00:33] a chance to catch up with me at any

[00:35] point and you do have questions about

[00:36] anything that comes up in these, please

[00:37] feel free to contact me and I'll uh I'll

[00:40] get back to you and I'll answer you as

[00:41] well as I can. So, um, there's a

[00:45] generally held belief in conference

[00:47] speaking that the the bravest or the

[00:49] stupidest thing you can do is a live

[00:52] demo.

[00:54] Um, I believe that I might have found

[00:57] something braver or stupider to do in a

[01:00] room full of PHP developers who are all

[01:03] hung over from a social last night who

[01:05] are just coming up to their lunch and

[01:08] are going to want to have

[01:10] that. I'm going to talk about

[01:13] golf. Now, I can see some people

[01:15] nervously looking to the door now. Um, I

[01:18] can assure you you don't need to know a

[01:20] single thing about golf to enjoy this

[01:22] presentation hopefully. Um, I personally

[01:25] I am a golfer. I like playing golf and I

[01:27] started writing a golf application um, a

[01:30] couple of years ago not using any of the

[01:33] techniques that I'm about to talk about

[01:34] today. And I recently started rewriting

[01:36] it using a lot of the techniques. So

[01:39] this uh, talk is going to have a little

[01:41] bit of a before and after element to it.

[01:43] I'm going to show you some of the code I

[01:44] did write. I'm going to show you some of

[01:45] the code I have now got. Um, and so like

[01:49] I say, there's a golf theme to it, but

[01:50] you really don't need to know anything

[01:52] about golf for that. Um, the other thing

[01:54] that I want to make perfectly clear is

[01:57] that I wrote the first version in Kana.

[02:00] Um, and I'm now working with Symphony.

[02:03] Um, but I want to state for the record

[02:05] that I like. I think Kohana is a great

[02:06] little framework. So, I don't want the

[02:08] takeaway point from this to be some form

[02:10] of framework flame war like me saying,

[02:13] "Oh, it's wrong in Kahan and it's right

[02:14] in Symphony." That's that's not the

[02:16] intent at all. Um, and thirdly, um, some

[02:20] of the coding examples I'm putting up

[02:22] are a combination of real code, pseudo

[02:26] code, exaggerations for effect. Um, and

[02:29] I will let you decide which you think is

[02:31] which.

[02:34] So we'll start with um two or three just

[02:36] examples of the code as I had it in

[02:38] Kahana. Um so the first thing we've got

[02:40] here is we've got a club a golf club. Uh

[02:44] extends a kahan. Uh it has a name. It

[02:47] has a a golf field where you go out and

[02:49] you play your golf and it has a course

[02:51] where you would go and learn how to play

[02:53] golf. I can see one or two golfers

[02:56] shuffling uncomfortably in the seats at

[02:58] some of the terminology there. And I

[02:59] will address that in time. Uh and

[03:02] there's also a function here to be able

[03:03] to book a tea off time at this

[03:06] club. We also have uh a simple

[03:09] controller to add a new club. It takes

[03:11] values in from the request uh and it

[03:14] saves a

[03:16] club. We have a details controller does

[03:19] the opposite of that. It takes a club,

[03:20] displays it out.

[03:24] and um another controller where we take

[03:27] in the user, we take in a club, we take

[03:29] in a date and we book a tea off time for

[03:31] this user. Like I say, the

[03:34] actual things that are that is happening

[03:37] there is not that important. It's just

[03:39] for illustration. Um and we'll compare

[03:41] them side by side as we go

[03:43] along. So the first part of this talk is

[03:46] domain driven design. Can I have a quick

[03:49] show of hands about how many people know

[03:51] and understand that

[03:53] term? Great. Is there many people in

[03:56] here who don't really know anything

[03:57] about domain driven design? This is a

[03:59] completely new term to them. Okay. Those

[04:02] people that raised their hands the

[04:03] second time round, um, are you strong

[04:05] with object

[04:06] orientation? Okay. So, I don't think

[04:09] you're going to learn too much new here.

[04:11] There's not going to be anything here

[04:12] that blows your mind in terms of, uh,

[04:13] domain driven design. And there's a lot

[04:15] of parallels between DDD and object

[04:18] orientation. So the first thing we're

[04:20] going to look at is the

[04:21] domain. Now the domain is essentially

[04:25] the sphere of knowledge. It's the thing

[04:26] you're writing your code

[04:29] about. So there's a quote here from Eric

[04:32] Evans who quite literally wrote the book

[04:35] on this. Um the book is called Tackling

[04:38] Complexity in the Heart of Software. It

[04:39] came out in 2003 and most subsequent

[04:42] writing on the subject comes from this

[04:45] book. It expands on this book. It takes

[04:47] the ideas put forth in this book and it

[04:50] um it elaborates on them but nothing

[04:53] really has changed much since this book.

[04:56] Uh and he says in order to create good

[04:58] software you have to know what that

[04:59] software is about which makes sense

[05:01] right? You um you cannot create banking

[05:04] system unless you understand what

[05:05] banking is about.

[05:07] Um, so you must understand the domain of

[05:10] banking to be able to write

[05:12] that. So your domain is a sphere of

[05:14] knowledge or influence or activity. It's

[05:16] it's what you're doing. It's the subject

[05:19] area to which a user applies a program

[05:21] and the domain evolves collaboratively.

[05:24] Now this is a topic I'll come back to

[05:26] again and again over the next 20 minutes

[05:28] or so.

[05:31] Um so I'm going to spend the first half

[05:33] of this talk as I say talking about DDD

[05:35] some of the principles involved in DDD

[05:38] and then I'm going to move on to

[05:38] hexagonal

[05:40] architecture. So

[05:42] um we have entities and value objects in

[05:46] in DDD. Now what I'm going to do here is

[05:50] I'm going to try a little

[05:51] experiment. Does anybody have a£10 note

[05:55] on them?

[05:58] Got a hand up here. I have a£10 note on

[06:03] me. Would you mind swapping your 10 note

[06:06] for my 10 pound note?

[06:09] Yes.

[06:11] Okay. So, you can see here two10 notes,

[06:13] two different£10 notes. This one here

[06:17] from the gentleman. This one here was

[06:18] mine. I'm going to take that and I'm

[06:20] going to swap

[06:24] that. Yeah. You happy with that

[06:26] transaction? Yeah. I can feel a sense of

[06:29] anticipation building. I can I can see

[06:32] people looking. What's happening here?

[06:34] It's a magic trick. It's not. Uh that

[06:37] was exactly as mundane as it looked. Um

[06:40] but the point is that I have a new 10

[06:44] note and you have a new 10 note. But

[06:46] this hasn't changed anything. These 10

[06:48] notes are equal. They are different, but

[06:51] they're equal. And the equality comes

[06:54] from the values held within. It is 10

[06:57] and it is pound sterling and that's how

[07:00] we compare them. These are value

[07:03] objects. Now I notice there you've got a

[07:06] laptop. You know we've just established

[07:10] here that um you know I like to do a

[07:14] trade. I've just done a successful

[07:16] trade. You've seen that partner here is

[07:18] happy with the trade. Would you be

[07:19] willing to swap your laptop for my

[07:26] laptop? Of course not. Of course not.

[07:29] And the reason for that is your laptop

[07:31] has state. Your laptop has the things

[07:34] that you have downloaded to it. Your

[07:35] programs, your files, your emails. Mine

[07:38] has state as well. It's got a picture of

[07:40] a train I drew last night.

[07:44] Um but the concept there is that that is

[07:48] a unique laptop. It is very much your

[07:52] laptop. It is individual. It's not

[07:55] interchangeable. It has as a value or

[07:58] sorry as an entity. It has an ID. It's

[08:01] specific to you. This one has an ID. So

[08:04] the differences there. Value objects are

[08:06] immutable. You don't change them. You

[08:08] know, we didn't upgrade this

[08:10] gentleman's£10 note by changing it.

[08:12] changing the picture of the queen.

[08:14] Although you could do that, I wouldn't

[08:15] recommend it. They don't have an

[08:17] identity in this system. They're just

[08:19] the equality is based on the values of

[08:20] them. Whereas the entities do they

[08:22] contain state the state changes over

[08:25] time. They describe the current status

[08:27] of the application and the equality is

[08:30] based on this

[08:32] identifier. I'll have you know last

[08:34] night when you're all at social, I went

[08:36] and bought that. That's my commitment to

[08:39] a visual gag.

[08:44] So let's talk a little bit about model

[08:45] driven

[08:46] design. Um so within the concept of um

[08:51] of DDD we have

[08:54] models. Models are the nouns in your

[08:58] domain. models represent the things you

[09:01] talk

[09:01] about when you talk outside the

[09:04] software, when you're talking with your

[09:06] product owners, when you're talking with

[09:07] your project managers, when you're

[09:08] talking with your clients, whoever it is

[09:10] you interact with, you talk about

[09:13] things.

[09:15] Um, and we want to make sure that we're

[09:18] naming these things as we talk about

[09:20] them outside the software, within the

[09:23] software. And I'm about to, excuse me,

[09:26] I'm about to come to that um in a bit

[09:28] more detail later on. They should be

[09:31] simple. Your models represent nouns.

[09:35] They represent entities. They represent

[09:38] behavior. But they also should adhere to

[09:40] the single responsibility principle.

[09:42] They do one thing. They know about the

[09:44] relationships. If anybody was at

[09:45] Marcelo's talk yesterday, he was talking

[09:47] in a similar vein about models. Um

[09:50] complex logic doesn't belong in there.

[09:53] Um, and if you get your model correct,

[09:57] it becomes trivial to enhance the

[09:59] application. You don't need to complete

[10:02] your model at the first pass. You just

[10:04] need to know what it is, how it

[10:06] interacts with certain things. And as

[10:08] your domain grows, you can add new

[10:10] models. You can add new relationships

[10:11] with these models, but it should be

[10:12] quite trivial because these things are

[10:16] small and simple. So, let's look back at

[10:19] the code here. We've got our club here.

[10:22] We've got a golf field and we've got our

[10:24] course uh which are strings. We're just

[10:27] having names in these right now, but

[10:29] these are things that we would talk

[10:31] about outside the

[10:34] um in in the real world. We would talk

[10:36] about as as actual things. A field is a

[10:39] thing. It's not just a string. It's not

[10:40] just a

[10:41] name. So, we should split that out and

[10:44] represent that. We have a model now to

[10:46] represent our golf field and we have a

[10:48] model now to represent our course.

[10:52] And then this becomes represented in our

[10:54] club as well. You'll notice that the

[10:55] string there has changed to the

[10:59] object. Let's talk about udicus

[11:03] language. What this essentially

[11:07] means um and again this is another quote

[11:09] from Eric Evans but what this basically

[11:12] means is talk in the same language.

[11:17] um be very very clear with how you're

[11:19] naming things and make sure that those

[11:20] names represent how people outside of

[11:24] the software talk as

[11:27] well. So we want to remove any

[11:29] ambiguity, any names that have meaning

[11:32] that could mean many things. It could

[11:33] mean depending on on who's talking about

[11:36] it. The language should be defined by

[11:38] the domain

[11:40] experts. And one thing to remember,

[11:42] you're not the target audience of your

[11:43] site in most cases. I know in some cases

[11:45] that will be the case. But crucially use

[11:48] the same language in the codes that you

[11:51] use when you're planning when you use in

[11:53] discussions when you use when you're

[11:55] writing that language should filter

[11:57] across throughout your company. The same

[11:59] thing should represented everywhere. So

[12:02] one example in my company that we saw um

[12:06] I work in wholesale retail B2B and in

[12:10] retail B2B we have the concept of

[12:13] forward orders and we have the concept

[12:15] of

[12:17] reorders. Now a forward order is

[12:19] essentially what I would think of as a

[12:21] pre-order. It's something that happens

[12:23] before stock is created. So the the

[12:26] retailer sorry the the brand makes

[12:28] available the stock says this is the

[12:30] things that are coming. We've not made

[12:32] any yet. We want you to place all your

[12:34] orders so that we know what the demand

[12:36] is so we can go and make them. And a

[12:38] reorder is what I or any of you would

[12:41] think of as an actual order. They come

[12:43] back after that initial period and they

[12:46] they order more. So to a degree they are

[12:48] reordering, but if you're thinking at it

[12:50] from a BTOC point of view, it's an

[12:53] order. You come to the website, you have

[12:54] it there, you press the stock, you go to

[12:56] the order, and you place it. And we had

[12:59] countless discussions internally with um

[13:02] a couple of developers who were adamant

[13:06] that this was an order. To them the word

[13:10] reorder made no sense and in a way I can

[13:13] understand that. Um it it is an order

[13:16] and they were thinking purely in that B

[13:18] to C term and the discussions and the

[13:21] arguments we had we have to call it an

[13:24] order. This is an order because it makes

[13:25] sense to me. I want to call it an order.

[13:28] We go back and say no, we can't call it

[13:29] an order because in our domain, our

[13:32] domain experts are talking about uh

[13:35] reorder. We have to reflect

[13:38] that. So you've heard me define the term

[13:42] domain experts a couple of times here. I

[13:44] want to do another little experiment

[13:46] here.

[13:48] Can you put up your hand if you are if

[13:52] you own a company? If you run a company,

[13:54] if you manage a company, can you put up

[13:57] your hand as well? If you work in

[14:00] product, you're a product manager,

[14:02] product

[14:03] owner. Can you put up your hands as

[14:06] well? if you are a business

[14:10] analyst.

[14:12] Okay. So, if you don't have your hand up

[14:15] right now, I hate to break it to you,

[14:18] but you're not the domain

[14:21] expert. Now, at Ray channel, uh I was

[14:25] lucky enough to be involved at the very

[14:26] start. I architected the system with

[14:29] with help from my team. Obviously, I

[14:31] have been involved in writing or

[14:32] reviewing pretty much every line of

[14:34] code. I understand implicitly the

[14:36] relationships between all the entities

[14:38] within our system. I know the

[14:41] domain, but a lot of our clients are um

[14:47] are brands in women's

[14:49] wear. I don't understand why retail

[14:52] buyers come to our system and they order

[14:55] lots of this and none of this. I don't

[14:59] understand when our brands are putting

[15:01] together their

[15:02] collections that this season everything

[15:05] has to be blue and polka dots. I don't

[15:09] understand why handbags cost

[15:13] £500

[15:15] when I paid £30 for that one and it

[15:17] carries

[15:19] more. I'm not the domain expert. I

[15:22] understand the domain in terms of

[15:24] software, but I'm not the domain expert.

[15:29] So let's look back at our code

[15:31] here. When I wrote this code,

[15:35] um, I was thinking about it from my

[15:37] point of view. A course to me is

[15:39] something you go on to learn. So it

[15:41] makes sense to call that thing a

[15:43] course. And a golf field makes sense.

[15:46] That's where you go and you go play. You

[15:48] play golf on the field. So I'm going to

[15:50] name these this way because that's what

[15:52] makes sense to me as a developer.

[15:53] Obviously, this is an awkward example

[15:55] because I'm the developer and the

[15:56] product owner and everything, but run

[15:58] with me here. Um, so I've chosen as a

[16:02] developer to name things this way

[16:05] because it makes sense to me as a

[16:06] developer. Now, imagine what happens

[16:08] when the product owner comes to me and

[16:10] says, "Okay, we need to change the cost

[16:13] of the course." And I look at it and go,

[16:15] okay, when you say course, do you mean

[16:18] the course you mean or do you mean the

[16:19] course I

[16:22] mean? This should

[16:24] reflect across the entire business. The

[16:28] words in the software need to represent

[16:29] the words outside of the

[16:34] software. So I'm going to talk about

[16:36] bounded context a little bit here. What

[16:39] a bounded context essentially is, it's a

[16:42] subdivision of your domain.

[16:44] So we spoke about your domain being your

[16:47] sphere of influence. It's it's

[16:48] everything about your business, but you

[16:51] can sometimes segregate that more. Um so

[16:54] to keep the the golf analogy going,

[16:56] imagine we have um a green keeper who is

[17:00] responsible for maintaining the the golf

[17:03] course itself. Uh we have the the club

[17:06] pro who is responsible for giving the

[17:09] lessons in the green keeper. They are

[17:13] they have a lot of tools for example

[17:15] that they would use. They're going to

[17:16] have a lawn mower. They're going to have

[17:18] all the uh all the tools they need to to

[17:20] cut the grass to to do everything they

[17:22] need to do. These things are very very

[17:25] specific to that small area of the

[17:28] domain. You know, the the club pro is

[17:30] not going to come along and and start

[17:31] using the lawnmower. Could if they

[17:33] wanted to, but that is we've got this

[17:36] little bounded context here that is for

[17:38] them. Likewise, the pro, they're going

[17:40] to have their their teaching calendar.

[17:42] They're going to have

[17:44] um uh a set of people they've had

[17:47] lessons with before and after. They're

[17:48] going to have the inventory of the club

[17:50] shop. Usually, the club pro runs a club

[17:53] shop. So, bounded context can have

[17:56] unrelated concepts. You've got the

[17:57] teaching calendar. You've got the lawn

[17:58] mower on one side, but it can also share

[18:01] concepts. So, think of the course, for

[18:03] example. the club pro is going to go and

[18:04] play on the course and the the green

[18:07] keeper is going to maintain the

[18:10] course. But what we've got to be wary of

[18:13] is that words and phrases mean different

[18:15] things in different contexts. So

[18:19] just without any context whatsoever, if

[18:22] I say the word ticket, what does that

[18:24] mean to

[18:26] you? I can guarantee there's about four

[18:28] or five different things going around

[18:30] the room at the moment. Everybody's got

[18:32] a different thing because I've not put

[18:33] any context on it

[18:35] whatsoever. So, think of, and again, to

[18:38] go back to our golf example, think of a

[18:41] bunker. Um, to those that aren't um

[18:44] proficient golfer, don't don't know that

[18:45] much about golf, a bunker is basically

[18:46] an obstacle on the golf course that's

[18:48] filled with

[18:49] sand. If you are the the club pro, the

[18:53] bunker, it's it's annoying. It's it's a

[18:55] thing that's there that when you're

[18:57] playing golf, you sometimes land in and

[19:00] you have to get out of it. It's a value

[19:04] object because it doesn't matter which

[19:06] bunker you're in as a pro. Just you're

[19:08] in a

[19:09] bunker. But if we think of it from the

[19:11] point of view of the green keeper, it's

[19:14] that specific bunker. It suffers with

[19:17] drainage in the winter, for example, and

[19:18] it tends to floods or the grass around

[19:20] the lip of it is too long. to the green

[19:24] keeper. These things are very specific.

[19:26] So things mean different things in

[19:28] different

[19:30] contexts.

[19:32] Okay. So

[19:38] services are the actions in your

[19:41] application. We spoke about the uh the

[19:44] nouns before we've built our models.

[19:46] Services the actions when something has

[19:48] to do something.

[19:51] Services cause state changes to

[19:53] entities but they do not have state

[19:57] themselves and we're still being driven

[19:59] by the same principles that we've just

[20:00] spoken about ubiquitous language and

[20:02] domain

[20:03] expertise. We still need to make sure

[20:05] we're having that discussion when

[20:07] something happens in our system. We have

[20:09] a service it represents a real world

[20:11] need that's spoken about. So let's look

[20:14] back at our model here our

[20:17] club. Um, we've got an action we want to

[20:19] perform here, which is booking a tea off

[20:21] time for a

[20:23] user. You notice the name of that

[20:25] function doesn't actually involve the

[20:27] word club and it's interacting with a

[20:30] number of different things. It's not

[20:32] really affecting the state of the club.

[20:34] It does depend on how you've modeled it.

[20:36] If the model if the club has a series of

[20:37] of tea off times within it, then

[20:40] perhaps. But how I would prefer to look

[20:42] at this is let's create a booking

[20:45] service and we have a a manager for

[20:48] booking tea times where we pass a user

[20:49] and a club into it. Now within this

[20:52] booking service which is name spaced off

[20:55] we could also have a restaurant booking

[20:57] manager. Uh many golf clubs have have

[21:00] restaurants as part of the complex.

[21:06] So continuous

[21:08] integration we move into next um CI is

[21:14] um was spoken about by Javi. Did anybody

[21:17] go to Jav's talk yesterday? Um well he

[21:20] was talking about continuous deployment.

[21:22] Uh whereas I'm stopping at the first one

[21:25] continuous integration

[21:27] here. Your domain is constantly going to

[21:30] evolve. It's going to change. is going

[21:32] to shift as you move into slightly

[21:35] different spheres of influence. What was

[21:37] right isn't going to be right anymore.

[21:39] We need to maintain discussion. We need

[21:42] to maintain take that step back and

[21:44] don't just furiously code. Let's take a

[21:46] step back and see is this changing

[21:49] anything that we used to take for

[21:51] granted. Testing strategies will help

[21:54] flag changes to this. If you are using

[21:57] uh for example PHP spec to build your

[22:00] domain and you have it making a certain

[22:03] set of expectations and somebody changes

[22:06] a domain your tests are going to break

[22:07] and that's a good point where you can

[22:08] look at it and go oh do we want to

[22:11] change these break these tests at this

[22:13] point is this a change we want to make

[22:14] or is this an accidental

[22:16] change but mainly merge code quickly and

[22:19] often. If you have two teams running off

[22:22] in different directions writing code,

[22:26] the domain is going to shift. They're

[22:28] going to make certain changes. It might

[22:29] be subtle. It might be big. But if you

[22:32] come six months later and try to merge

[22:34] that code back in when two teams have

[22:36] started going in that direction, it's

[22:38] going to be hard. You should always look

[22:40] to keep changes small, iterative, merge

[22:43] quickly, merge often.

[22:48] So these are just a few tips that I've

[22:50] had from the the successful application

[22:52] of DDD with the projects I've worked on.

[22:55] So crucially build models as a

[22:58] collaboration. This isn't

[23:00] just product owner, product manager,

[23:02] business analyst comes to you and says I

[23:04] want this go and do it. This is a

[23:06] collaborative process between both teams

[23:08] to work out how to approach this. The

[23:11] domain experts know how it works in the

[23:13] real world. you know how it works in the

[23:15] software world. Come together and work

[23:18] out the best way to make that work so

[23:20] that we can apply the principles we've

[23:22] just spoken

[23:23] about. Build your application

[23:25] iteratively, small chunks. We don't need

[23:27] to solve this problem. Again, Marcelo

[23:29] spoke about this last night. Big design

[23:31] up

[23:31] front. Accept your domain will evolve

[23:34] and change. You don't have to get this

[23:36] absolutely spot on first

[23:38] time. Have complete access to a domain

[23:40] expert. This is one of the most key

[23:42] things that I found in successful

[23:44] projects

[23:46] is when somebody who's invested in the

[23:49] delivery of the project is

[23:51] available 90 95% of the time it's easy

[23:55] because you can ask them questions. Did

[23:57] you mean this? Is this what you want?

[23:59] I'm not sure what this means. Can you

[24:00] clarify it for me? If you don't have

[24:03] that, you're guessing. If you're

[24:05] guessing, like I said before, you're not

[24:07] the domain expert and you're going to

[24:10] probably guess wrong. And I think Marcel

[24:13] is going to kick my ass for this one.

[24:16] Test, test, test. Um, if you can, so

[24:20] what Marcela spoke about yesterday is

[24:21] what you're not doing. You're not

[24:22] testing, you're specking. And I do agree

[24:25] with that. But the output of specking is

[24:28] that you have a test suite. If you can

[24:30] write these tests up front as you go

[24:32] along, that would be brilliant because

[24:34] like we just said, if you have a

[24:37] breaking change and it is reflected in a

[24:40] test that breaks, then that will be

[24:42] flagged up very quickly and you can see

[24:45] did we mean to do this? Do we want to

[24:47] change the behavior of this domain or is

[24:49] that accidental?

[24:53] So if you take nothing else from this

[24:55] talk, if there's only one tip you take,

[24:58] please let it be that talk with each

[25:04] other. So why are we not all doing this?

[25:06] Why do we don't all just well it's it's

[25:09] the

[25:10] future? I use the word downside here. I

[25:13] don't necessarily believe that is true.

[25:15] That's why I use ish. Um but there is no

[25:19] doubt it's time consuming especially

[25:21] initially to set this up to start

[25:23] changing your mentality to start

[25:25] changing your thinking to put the

[25:27] infrastructure in place to start putting

[25:29] testing mechanisms in place up front to

[25:31] start putting enhanced discussions

[25:34] there. It's time consuming but you

[25:36] notice the star there. It's timeconuming

[25:38] initially but this pays itself back

[25:40] manifold um towards the middle and end

[25:44] of a project.

[25:45] It can be confusing if you don't

[25:47] understand the domain. We just spoke

[25:49] about orders versus reorders versus

[25:50] forward orders. If a new developer comes

[25:53] into a system, you know, you've got your

[25:55] language, you've got your way of

[25:56] speaking, they're not going to

[25:57] understand it necessarily at first. You

[25:59] have to take the time to educate them,

[26:00] to bring them up to speed so they

[26:02] understand what you're talking

[26:05] about. And there is an overhead in

[26:08] maintaining constant dialogue.

[26:10] A lot of your managers, your bosses will

[26:13] think, okay, you're a developer, you sit

[26:14] there for eight hours a day, head down,

[26:17] code away. If you're having if you're

[26:19] having discussions, you're not

[26:20] delivering anything. Again, to me,

[26:23] that's not a downside. I can see why it

[26:25] could be perceived as, but having that

[26:28] discussion means you're more likely to

[26:30] get it right first time.

[26:36] Okay, so we have now evolved our code

[26:41] from the first iteration. We've got it

[26:43] now nicely cut off into a domain. So I'm

[26:46] going to talk a little bit about

[26:49] geometry. So what are we trying to

[26:51] achieve with hexagonal architecture?

[26:53] There's a quote there from Alistar

[26:55] Cockburn who is kind of the authority on

[26:58] this. If you've not read his blog, then

[27:00] it's it's the first one that comes up

[27:02] when you type hexagonal architecture and

[27:04] it's well worth a read. He says, "Allow

[27:07] an application to be equally driven by

[27:09] users programs, automated tests or batch

[27:11] scripts and to be developed and tested

[27:13] in isolation from its eventual runtime

[27:15] devices and

[27:17] databases." Obviously, what does that

[27:20] actually mean? It means that if you

[27:22] split your domain well enough, then

[27:26] there's going to be many things in the

[27:27] outside world that want to interact with

[27:29] it. You're going to want to retrieve

[27:31] data from multiple sources. Perhaps you

[27:34] have an XML reader, you have an HTML

[27:36] front end, you have an API, and you may

[27:39] need to output data to multiple sources.

[27:42] You could be using you could be

[27:44] using Reddus, you could be using

[27:46] MySQL. Doesn't matter inside your

[27:49] domain. Your domain does not care. Your

[27:51] domain cares about I have this object

[27:54] and I want it

[27:56] persisted. That's all I care

[28:00] about. And this is the question that I

[28:03] anticipated would come up most often

[28:05] than not. The hexagon is not a hexagon

[28:08] because the number six is important. It

[28:09] could be pentagonal architecture,

[28:11] octagonal architecture, docahedronagonal

[28:15] architecture, but rather to allow people

[28:17] doing the drawing to have room to insert

[28:18] ports and adapters as they need, not

[28:21] being constrained by a one-dimensional

[28:22] layer diagram. So, traditionally, this

[28:24] would be viewed left to right, top to

[28:28] bottom. Um, and the hexagon just gives a

[28:31] visual effect. So, this is another image

[28:33] that came from Alyssa Cockburn's blog.

[28:36] You can see um we speak traditionally

[28:40] and again to reference Marcelo's talk

[28:43] yesterday he spoke about um abstractions

[28:46] deal with abstractions and push the

[28:49] concretions down and away. Um if you

[28:52] were at that you remember that slide top

[28:54] left push the concretions down and away.

[28:57] What I'm saying is basically the same

[28:59] thing but I'm saying push them out and

[29:02] away. Your application he uses the word

[29:05] application here. This is what we've

[29:06] just described as a domain sits in the

[29:09] middle here and push the concretions

[29:11] outside of

[29:14] it. So let's look back at our

[29:19] club. We're extending the OM in the club

[29:23] here. This is a um the way that Kohana

[29:26] uses OM to give you essentially active

[29:31] records. what this

[29:34] means. And I apologize for this diagram.

[29:38] Um, I had a friend that helped me write

[29:40] most of the slides, so they look

[29:42] generally quite nice cuz he's good at

[29:43] that kind of thing. I had to do this

[29:44] myself. It kind of

[29:47] shows. Um, but the principle of the

[29:50] thing

[29:51] is we want all the dependency arrows to

[29:55] flow

[29:56] inwards. Um, and just actually one thing

[29:59] that may be slightly confusing, you'll

[30:01] notice here there's two hexagons. And

[30:04] you'll notice here there's two hexagons.

[30:07] My outer hexagon here represents his

[30:10] inner hexagon. Um, just to confuse you

[30:13] even more, obviously.

[30:15] Um, this isn't necessarily something

[30:18] that you would need to do or want to do.

[30:20] I just prefer to do it that way. I like

[30:22] to split the domain models inside and

[30:26] put the services wrapped around that and

[30:28] then put the application layer around

[30:31] about that and that's the outer hexagon

[30:33] that Alistister Cogburn talks about. So

[30:36] you see we've got our controllers coming

[30:38] in through managers through our

[30:40] services. The services bring come in

[30:42] towards our um models. Everything's

[30:46] great so far. That's what we want to

[30:48] see. But the red arrows there, they're

[30:51] coming back out now. There's kahana now

[30:53] lives within our domain and is important

[30:55] within our domain and we don't want that

[30:57] to be the

[31:00] case. So let's talk about ports. If you

[31:03] noticed on the first slide um when I

[31:06] mentioned hexagonal architecture, it

[31:08] also said ports and adapters. Ports and

[31:10] adapters is just a different term for

[31:12] that. So ports are the gateways into

[31:15] your domain. they define the purpose of

[31:17] the

[31:20] conversation. Um, so like I mentioned

[31:22] before, you know, you want to store data

[31:25] somewhere, but your domain doesn't care

[31:28] where. So if we have another quick look

[31:30] at this diagram here, the lines, the the

[31:34] bold lines where it says database,

[31:36] notifications, where it says user data,

[31:39] where it says administration, these are

[31:40] the ports in our uh application here. or

[31:45] sorry that's confusing because he uses

[31:47] application in our system here.

[31:50] Um what the ports are for is to say okay

[31:55] you can save data I'm the database port

[31:58] and I will give you the contract of how

[32:00] to save data but how you then use that

[32:03] is up to

[32:04] you. So let's illustrate that with a

[32:07] little bit of

[32:08] code. So I've got my club now and what

[32:11] I'm building is a club repository.

[32:14] The club repository is this uh contract.

[32:18] Now it says if you want to persist a

[32:22] club then you have to adhere to the

[32:25] rules applied by this port. You can save

[32:28] a club and you can find a single club by

[32:31] its ID. That's all you can

[32:34] do. I don't care how you do it. I don't

[32:37] care where you put it. But that's the

[32:39] two things you can do.

[32:43] And now we look at our club. So we are

[32:47] no longer using Kahano RM. So we need to

[32:49] build in our constructor now which came

[32:51] for free

[32:53] previously. Um but nothing much more has

[32:56] changed. We still got our simple club.

[32:59] Um I've started name spacing a little

[33:01] bit here um just to help the

[33:02] illustration but it's not overly

[33:04] important for this

[33:05] example. Um but the important point is

[33:08] we now get a constructor. build our

[33:10] club, but a club doesn't know how to

[33:12] save itself. Um, I missed a code I

[33:15] wanted to put another slide in here that

[33:16] I forgot to put in. I apologize. Uh, our

[33:19] constructor, uh, sorry. Um,

[33:22] originally

[33:24] our No, I'm not going to go back to it.

[33:27] Um, we were calling club save. The club

[33:30] knew how to save itself. And this came

[33:32] from the OM. And that was showed the

[33:35] arrow flowing back outwards. the club

[33:37] knew about application logic. Now we

[33:39] don't have that. Now we pass a club into

[33:41] the repository that knows how to save

[33:46] itself. So we've got our ports. So the

[33:49] second part of this contract is

[33:53] adapters. Adapters are built on top of

[33:55] the ports and they provide functionality

[33:59] concretely. And you can have multiple

[34:02] adapters. you probably will have

[34:04] multiple

[34:05] adapters. So for

[34:09] example, here is a very specific

[34:11] adapter. We implement the club

[34:13] repository. We're using the port. We're

[34:15] using that set of rules we've

[34:17] defined and um through space obviously

[34:20] I've commented out, but that would be

[34:22] some SQL that would save a club. Some

[34:25] SQL to find a club and return

[34:29] it. I want to save it in

[34:34] same port, same simplistic I can save

[34:38] it, I can find it. And that's your your

[34:40] language to um to save those to um

[34:44] find one by

[34:45] ID. And so a major advantage of this is

[34:49] you wanted to swap your storage

[34:51] mechanism out for from MySQL to

[34:54] for some reason. That's how easy it is.

[34:56] That slightly trivializes it obviously,

[34:59] but your domain doesn't care. Your

[35:02] domain doesn't

[35:03] change. No behavior has changed at all

[35:06] in your domain. You just build another

[35:09] adapter, configure it to use that

[35:11] adapter now, and you're now using

[35:16] So, we've got a file system club

[35:18] repository. This is how we test. We

[35:21] build um we use Bhat and we use file

[35:25] system. So when we configure when Bhat

[35:27] spins up instead of configuring the

[35:29] MySQL adapter, it configures the file

[35:31] system adapter. Um it's quicker. We

[35:34] don't need to go near the database when

[35:35] we're running our test suite. We've just

[35:37] got an adapter. Same contract. We're

[35:39] still using the club repository. We

[35:41] still got just our two simple

[35:46] methods. And now we go back to the

[35:48] controller here. So where I did have as

[35:51] I just mentioned that save function now

[35:54] we're passing the club into the club

[35:55] repository

[35:57] uh and we're saving it that way. We've

[35:58] defined our

[36:03] contract. So now we look a little bit

[36:05] like this in the

[36:07] hexagon. So these two repositories the

[36:10] club repository and the tea time

[36:11] repository are now the ports into our

[36:14] system. Anything that wants to save

[36:15] anything into a data storage has to come

[36:18] through these repositories. And you'll

[36:20] notice that we've got a Reddus one and a

[36:22] MySQL one coming through there depending

[36:24] on how we configure it, depending on

[36:26] what we're running at any given

[36:30] time. But you'll see the red line here,

[36:34] the create club controller is still

[36:36] going directly into our domain. It still

[36:39] knows how to manipulate. If you go back

[36:41] a slide here, we're still creating a new

[36:43] club directly.

[36:48] We need a port at the other side

[36:52] here. So we've got a club

[36:55] porter. Um I use the word porter because

[36:58] it's to do with the import and export of

[37:00] data in and out the system to the UI. So

[37:03] it's portation. It's a porter. Um we've

[37:06] defined two two rules. You can either

[37:09] import a club with mixed data depending

[37:11] on where it's coming from or you can

[37:12] export a club which sends a club which

[37:15] takes a club and exports mixed data. So

[37:18] let's see a concrete realization of

[37:21] that. We've got a request club porter

[37:24] takes in a request builds our club from

[37:27] the information

[37:29] um and we can export a club by taking

[37:31] the club putting the data into the

[37:33] response and returning that. As I said

[37:35] before that some of the code examples

[37:37] are are pseudo code just for

[37:39] illustration rather than than real

[37:41] genuine

[37:42] code. But the advantage we have here is

[37:46] that same thing. We don't want to take

[37:49] in a request anymore. We want to take in

[37:51] JSON. We want to take in HTML. We want

[37:53] to take in

[37:56] XML. So let's go back to our controller.

[37:59] Now all of a sudden I've got a oneline

[38:02] controller.

[38:05] Um, data comes in through the porter.

[38:08] Data gets saved through the

[38:12] repository. Domain doesn't care where

[38:14] it's coming from. Domain doesn't care

[38:16] where it's going

[38:19] to. So, this gives us expands the

[38:23] diagram a little bit here. And now we

[38:25] can see the flow of arrows is all coming

[38:29] in. the the users, the clubs, the

[38:32] models, they don't care where the data

[38:33] is coming from. They don't care how

[38:35] they're made. They don't care anything.

[38:37] The services don't care where the data

[38:39] comes from. They know what they have to

[38:41] do. And the concrete implementations are

[38:44] based on

[38:49] configuration. So, what sort of ports

[38:52] should there be? Um, traditionally in a

[38:55] web application, you're not going to

[38:56] need that many. Alistister Cockburn when

[38:59] he originally wrote his slides he was

[39:02] dealing in enterprise software big big

[39:05] behemoth systems and he said he'd never

[39:07] seen more than four um traditionally as

[39:10] I say in a web app you're not going to

[39:12] see much more than than a couple data

[39:15] comes in and out to screen to UI data

[39:17] gets persisted into a database

[39:20] um you could maybe have logging ports

[39:23] notification ports if you needed

[39:25] that But

[39:27] um the hexagon as I say is not you don't

[39:30] need to have six ports. There aren't six

[39:32] defined ports. It's just an illustration

[39:34] of a number of

[39:38] ports.

[39:40] Okay. Thank you for your time.

[39:44] [Applause]

[39:54] Like I say, if um if you do have any

[39:56] further questions on this and you do

[39:57] want to try and contact me and you don't

[39:59] get a chance to see me today, then

[40:01] please feel free to contact me through

[40:02] those

[40:04] um places.

[40:06] And that's a reference to the book that

[40:09] Eric Evans wrote. The second link is a

[40:12] um it's a PDF that summarizes the book.

[40:16] Um I built a lot of the first part of

[40:18] the the talk on that and that's uh also

[40:21] Cobburn's blog on hexagonal architecture

[40:23] is worth reading as well.

[40:28] Yeah, if there's any

[40:33] questions there

[40:36] I go first. Yeah.

[40:41] Okay. So am I going first or? Yeah, go

[40:44] ahead. Okay, Gordon, what would you

[40:47] suggest for a team uh so if your team

[40:51] leading a team and some of the people in

[40:54] the team still not up to speed with DDD,

[40:57] how do you recommend the team lead to

[40:59] kind of u bring them up to speed, what

[41:01] what kind of things did you Well, the

[41:03] main thing I would suggest um did

[41:05] everybody hear the question? Okay, it's

[41:07] how to introduce new team members to TDD

[41:09] or to DDD. The main thing is as I say

[41:13] like the main point I put across it's

[41:15] communication. Take the time. Um the

[41:19] domain language you use is going to

[41:21] become second nature to you. You're

[41:22] going to refer to things without

[41:23] thinking about it. So it just it's a

[41:27] slow process. You have

[41:29] to go through with them. You have to

[41:31] make sure they're involved in a lot of

[41:33] meetings with you. So don't split out

[41:35] the meetings into well these two guys

[41:37] know about this so they're going to sit

[41:39] and have this discussion and nobody else

[41:41] is going to know. Try and involve as

[41:42] many people as you can in those

[41:44] discussions when you're talking about

[41:45] domain objects when you're talking about

[41:47] models uh when you're talking about

[41:48] behaviors of the domain so that it

[41:51] becomes second nature to people over

[41:53] time that they'll start picking it up.

[41:55] Uh in terms of the techniques you can

[41:57] use certain things you can use pairing

[41:59] with more senior developers who do

[42:01] understand it. um code reviews um

[42:04] helping pick out uh maybe places they've

[42:07] gone wrong sit with them help them

[42:09] understand okay I see what you were

[42:11] trying to do there but maybe you know we

[42:13] try to approach a problem this way help

[42:15] them understand why to do that um but

[42:18] it's just continuously working with them

[42:21] um and investing that time uh like I

[42:24] said there's there is some overheads and

[42:26] this is an overhead that's worth it

[42:28] invest the time team lead may have to

[42:31] take a cut in how they can actually

[42:32] deliver during that. They're maybe not

[42:34] doing so much programming during that

[42:35] time, but if they invest the time, then

[42:38] the team as a whole grows through that.

[42:41] Does that help?

[42:44] Hi. Um could you come back to your

[42:47] hexagonal row? This one here.

[42:52] Yeah. Um my question is uh if you talk

[42:56] about um um your code

[42:59] domain so why the the service is out of

[43:03] this domain of this core sorry they are

[43:06] not. So this was what I spoke about when

[43:08] I said it was maybe slightly confusing

[43:10] between the two um diagrams. My core

[43:13] domain here is the outer hexagon and I

[43:16] split the inner hexagon to be the domain

[43:18] models

[43:20] but the outer hexagon is domain. So the

[43:22] domain still contains the services but

[43:25] if if you you could go to the controller

[43:28] please. One second.

[43:31] Sorry. Yeah.

[43:33] Yeah. You you're calling here direct to

[43:36] the

[43:37] repository and um I don't know why

[43:40] you're doing this instead of uh calling

[43:42] from your service that it's from your

[43:44] domain. I mean if you have the interface

[43:48] you only need the the implementation in

[43:50] the controller. Yes. Um absolutely right

[43:53] and this is a conversation I had about

[43:55] half an hour ago before I started

[43:57] myself. Um you would perhaps want to so

[44:01] what I'm trying to illustrate mainly

[44:03] here is the the data comes in in a

[44:08] format. it comes through a porter which

[44:11] is defined by the port and it's now in

[44:13] your domain and it goes out through a

[44:16] repository

[44:17] um through a specific one. So that's the

[44:20] layer I'm trying to enhance uh to show

[44:22] here. Um I'm using a controller as um

[44:27] because we're you it's we're generally

[44:29] web developers here so we do use

[44:30] controllers but what you might want to

[44:32] do is abstract that knowledge into the

[44:35] domain as well. have a service that

[44:37] deals with um converting the data from

[44:41] the controller into the format that your

[44:44] uh concrete adapter would then use in

[44:46] the domain in that model. Um so yes,

[44:49] perhaps that's maybe not clear. And the

[44:51] other thing that um to follow up on the

[44:53] point you just mentioned there that I

[44:54] was um thinking is that the controller

[44:58] here points at the porter, but if you

[45:00] actually look at the code, it also comes

[45:01] around the other side and points at the

[45:03] repository as well.

[45:05] So the controller itself doesn't quite

[45:07] fit this model. Um I I tried to draw it

[45:09] in here just for illustration that um

[45:12] it's there. What you would maybe want to

[45:14] do is have another service like you say

[45:17] inside the domain that um that takes

[45:20] that converts the data through the

[45:21] controller. We would use a param

[45:22] converter for example to do that um and

[45:26] uh use that uh that process.

[45:30] Okay. Does that make sense? Yeah. Yeah.

[45:33] the controller the controller doesn't

[45:36] quite fit the model. I agree with what

[45:38] you're saying there. The important part

[45:39] I was trying to illustrate was data's

[45:42] coming in in one format. You use a

[45:44] concrete um implementation of a port to

[45:47] get it into your domain.

[45:50] Thank you.

[45:56] One over here. One over there.

[46:00] Yeah. Good.

[46:08] Hi um thanks for the talk. Um I was

[46:11] wondering I work in a large organization

[46:14] with different teams in you know in

[46:16] different countries for example so the

[46:18] bounded context stuff is quite

[46:19] interesting. Have you got any advice on

[46:21] on how that scales and what are the

[46:23] artifacts and agreements that you you

[46:25] end up with?

[46:27] Um not great advice because I work in a

[46:30] startup. I work in a very small um code

[46:33] base. Uh how I would have approach or

[46:35] how I approached that within our system

[46:38] is through name spacing.

[46:41] Um

[46:43] and so you you split it out that way.

[46:45] But it's not a problem to be honest that

[46:48] I've solved myself. Um because generally

[46:51] speaking, a lot of the um code bases I

[46:54] work with are quite small. They are

[46:55] quite contained. They're not as

[46:57] sprawling unfortunately. So I don't have

[46:59] that much advice I could give you there.

[47:02] Um okay I have one other question. Um

[47:04] we've used a lot of terms like value

[47:06] objects, models, services and then

[47:09] overlapping that with standard MVC um

[47:12] web frameworks. So could you give like a

[47:15] a summary of of how these things map or

[47:17] or where they don't map well?

[47:20] Uh that would be a talk in itself I

[47:22] think um to do it properly. But um like

[47:25] I said at the start uh in terms of OO um

[47:30] design most of us are relatively okay

[47:33] with that. You know your models map to

[47:35] your objects. Um so the concepts do

[47:39] cross over in terms of MVC. You're

[47:42] seeing we're still using uh a

[47:44] controller. The model becomes the domain

[47:47] really. You're working with the full

[47:48] domain even if you're only using parts

[47:50] of it. the view is is coming through the

[47:54] port. So you are you're using your

[47:56] porter to export data. You might have an

[47:58] HTML porter that ports to that. Um you

[48:02] might use an API to export the

[48:04] information out that a front end can

[48:06] then consume. Um so the V is almost

[48:11] irrelevant in MVC. Um with this

[48:13] hexagonal architecture you just you

[48:15] output uh your models in AI and how the

[48:20] the front end would then consume that is

[48:22] up to

[48:22] it. Um in terms of O like I say much of

[48:26] the much of the structure is the same.

[48:28] You have objects that interact with each

[48:30] other. The principles of keep your

[48:32] objects small still apply. The

[48:34] principles of dealing with abstractions

[48:36] encapsulation they all still apply. So

[48:39] there's

[48:40] nothing there's not a huge shift in

[48:42] mentality required to start thinking in

[48:44] terms of DDD. The biggest shift is the

[48:49] conversational aspect of it and

[48:50] understanding that

[48:52] um there are people employed in your

[48:55] organization who do know the domain

[48:57] better than you. So let them help you.

[49:01] But for example um you know in your

[49:03] diagram um which ones are the services

[49:05] which ones are the entities where are

[49:07] the models in in that what I've tried to

[49:10] do with this uh diagram if you can bring

[49:12] it back up onto the screen

[49:15] please is the color code here. So the

[49:18] inner hexagon are my models. Those are

[49:21] the simple objects. There's club there's

[49:24] course they can interact with each

[49:25] other. The club knows about the course.

[49:28] The second layer uh color coded in

[49:31] green, these are our services that

[49:33] interact directly with our models. But

[49:35] you notice that our models don't

[49:36] interact backwards with the services.

[49:38] And then external to the hexagon. So

[49:40] this goes into our application layer um

[49:43] start dealing with the services

[49:45] themselves.

[49:48] That's helpful. Thank you. Yeah. Hi

[49:50] there. Um great talk. Um interested when

[49:53] you're talking about the uh naming and

[49:57] say um later down the line the domain

[50:00] experts realize they've made a mistake

[50:02] and a user should be called a player.

[50:04] Would you go to the extent of renaming

[50:07] all the users in the code to to players?

[50:12] Ideally yes I would. Um but there has to

[50:15] be a time and place for it.

[50:18] Um I'm not generally a fan of

[50:21] refactoring for refactoring state

[50:23] stopping and um you know just having

[50:26] we're just going to do code now. Um I do

[50:28] believe in always moving the business

[50:30] objective forward. So at a point where

[50:33] it made sense to do that I would do it

[50:36] but the short answer is yes I would

[50:38] advocate doing that.

[50:42] Um one more about naming which seems to

[50:45] be uh very important. Um if you're

[50:48] coming from a design pattern backgrounds

[50:50] uh you will most likely use a lot of

[50:52] names like this is something factory or

[50:55] observer or anything. What is conflict

[50:57] with using uh domain based naming or do

[51:02] they work together because they don't

[51:03] apply to actually the same entities? I

[51:06] believe that you can um and you'll

[51:09] notice I use the word collaboratively

[51:11] quite often. Um it's not necessarily the

[51:14] fact that you have to adhere to what

[51:16] your domain expert says because you know

[51:20] you guys are the technical experts and

[51:22] there is a a middle ground. You should

[51:26] always try as much as you can to to name

[51:28] things as people as things are going to

[51:29] be named but it might not always be

[51:31] possible. There might be ways of naming

[51:33] things. You might call something for

[51:34] example a factory or an observer. That's

[51:36] perfectly okay as long as there's still

[51:38] a description that maps to the outside

[51:40] world.

[51:47] Hi there. Do you have any advice for

[51:49] structuring the um application? Do you

[51:52] have like a a domain uh a namespace for

[51:54] your models and your services or do you

[51:56] mix them together?

[51:59] How I tend to do it is at the the root

[52:02] source folder. Um I would have name

[52:05] spaces for each of my domain models. So

[52:07] a user um I would have a club course

[52:12] would maybe live within club. Um the the

[52:16] services live at that level as well. But

[52:18] you'll notice if I go back

[52:23] um I use the word service there. The

[52:26] services live within there but they live

[52:27] at the same level. Uh like I say this is

[52:30] personal preference. I'm not saying that

[52:32] this is necessarily right or wrong.

[52:34] Um and then we have a folder as well at

[52:38] that level called infrastructure and our

[52:42] doctrine uh lives in there or symfony

[52:44] lives in there. All our controllers live

[52:46] in there that um are essentially outside

[52:49] our domain. So the three layers live at

[52:53] the same layer within the code. Um you

[52:55] could what I have done in the past is

[52:58] split out the model layer into its own

[53:01] um subdomain as well. So you have model

[53:03] slash user slash user model

[53:07] clubcourse. Um it's partially down to

[53:11] personal preference I think but as long

[53:13] as there is a clear distinction to you

[53:15] and it makes obvious to you and your

[53:17] team um then I think there are there are

[53:21] ways to do it that suit that suit you

[53:23] that's just how we choose to do it.

[53:25] Thank you.

[53:27] Any more questions?

[53:42] Okay, thank you everyone.

[53:45] [Music]

[54:13] I don't

[54:14] think I

[54:18] want I want

⚡ Saved you time reading this? Transcribe any YouTube video for free — no signup needed.