---
title: 'Gordon Skinner - Hexagonal Architecture in DDD'
source: 'https://youtube.com/watch?v=u6oTg5oRH24'
video_id: 'u6oTg5oRH24'
date: 2026-06-15
duration_sec: 0
---

# Gordon Skinner - Hexagonal Architecture in DDD

> Source: [Gordon Skinner - Hexagonal Architecture in DDD](https://youtube.com/watch?v=u6oTg5oRH24)

## 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.

### Key Points

- **Introduction to Domain-Driven Design** [03:46] — 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.
- **Entities vs Value Objects** [05:42] — Value objects (like £10 notes) are immutable and equal based on their values. Entities (like laptops) have identity and mutable state.
- **Model-Driven Design** [08:44] — 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.
- **Ubiquitous Language** [11:03] — 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.
- **Bounded Context** [16:36] — Subdivide the domain into bounded contexts where terms may have different meanings. Example: 'bunker' means different things to a club pro vs a greenkeeper.
- **Services in DDD** [19:38] — Services represent actions that cause state changes to entities but do not have state themselves. They should be named based on real-world needs.
- **Continuous Integration and Domain Evolution** [21:08] — Domains evolve; merge code quickly and often. Testing strategies (like PHPSpec) help flag unintended changes.
- **Tips for Successful DDD** [22:48] — Build models collaboratively, iterate, accept domain evolution, have access to domain experts, and test extensively.
- **Hexagonal Architecture Goals** [26:49] — Allow the application to be driven by users, programs, tests, or batch scripts, and developed in isolation from runtime devices and databases.
- **Ports and Adapters** [31:03] — Ports define contracts for interactions (e.g., saving data). Adapters provide concrete implementations (e.g., MySQL, Redis, file system).
- **Example: Club Repository** [33:43] — A repository interface defines save and find methods. Concrete adapters implement these for different storage backends.
- **Porter for UI Data** [36:48] — A porter handles import/export of data to/from the UI, allowing controllers to be thin and domain-agnostic.

### Conclusion

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.

## Transcript

So first things first, who am I? Uh my
name is Gordon. Uh at the moment I work
for a startup called Re channel. Been
doing that for a few months. Previously
I was a team lead at Enva. Before that I
was a senior developer at Moo and before
that I did some net. Um you can contact
me on these two um places. I'm generally
not good at responding but give me a
prod. I'll get back to you. Um, but
generally honestly, if if you don't get
a chance to catch up with me at any
point and you do have questions about
anything that comes up in these, please
feel free to contact me and I'll uh I'll
get back to you and I'll answer you as
well as I can. So, um, there's a
generally held belief in conference
speaking that the the bravest or the
stupidest thing you can do is a live
demo.
Um, I believe that I might have found
something braver or stupider to do in a
room full of PHP developers who are all
hung over from a social last night who
are just coming up to their lunch and
are going to want to have
that. I'm going to talk about
golf. Now, I can see some people
nervously looking to the door now. Um, I
can assure you you don't need to know a
single thing about golf to enjoy this
presentation hopefully. Um, I personally
I am a golfer. I like playing golf and I
started writing a golf application um, a
couple of years ago not using any of the
techniques that I'm about to talk about
today. And I recently started rewriting
it using a lot of the techniques. So
this uh, talk is going to have a little
bit of a before and after element to it.
I'm going to show you some of the code I
did write. I'm going to show you some of
the code I have now got. Um, and so like
I say, there's a golf theme to it, but
you really don't need to know anything
about golf for that. Um, the other thing
that I want to make perfectly clear is
that I wrote the first version in Kana.
Um, and I'm now working with Symphony.
Um, but I want to state for the record
that I like. I think Kohana is a great
little framework. So, I don't want the
takeaway point from this to be some form
of framework flame war like me saying,
"Oh, it's wrong in Kahan and it's right
in Symphony." That's that's not the
intent at all. Um, and thirdly, um, some
of the coding examples I'm putting up
are a combination of real code, pseudo
code, exaggerations for effect. Um, and
I will let you decide which you think is
which.
So we'll start with um two or three just
examples of the code as I had it in
Kahana. Um so the first thing we've got
here is we've got a club a golf club. Uh
extends a kahan. Uh it has a name. It
has a a golf field where you go out and
you play your golf and it has a course
where you would go and learn how to play
golf. I can see one or two golfers
shuffling uncomfortably in the seats at
some of the terminology there. And I
will address that in time. Uh and
there's also a function here to be able
to book a tea off time at this
club. We also have uh a simple
controller to add a new club. It takes
values in from the request uh and it
saves a
club. We have a details controller does
the opposite of that. It takes a club,
displays it out.
and um another controller where we take
in the user, we take in a club, we take
in a date and we book a tea off time for
this user. Like I say, the
actual things that are that is happening
there is not that important. It's just
for illustration. Um and we'll compare
them side by side as we go
along. So the first part of this talk is
domain driven design. Can I have a quick
show of hands about how many people know
and understand that
term? Great. Is there many people in
here who don't really know anything
about domain driven design? This is a
completely new term to them. Okay. Those
people that raised their hands the
second time round, um, are you strong
with object
orientation? Okay. So, I don't think
you're going to learn too much new here.
There's not going to be anything here
that blows your mind in terms of, uh,
domain driven design. And there's a lot
of parallels between DDD and object
orientation. So the first thing we're
going to look at is the
domain. Now the domain is essentially
the sphere of knowledge. It's the thing
you're writing your code
about. So there's a quote here from Eric
Evans who quite literally wrote the book
on this. Um the book is called Tackling
Complexity in the Heart of Software. It
came out in 2003 and most subsequent
writing on the subject comes from this
book. It expands on this book. It takes
the ideas put forth in this book and it
um it elaborates on them but nothing
really has changed much since this book.
Uh and he says in order to create good
software you have to know what that
software is about which makes sense
right? You um you cannot create banking
system unless you understand what
banking is about.
Um, so you must understand the domain of
banking to be able to write
that. So your domain is a sphere of
knowledge or influence or activity. It's
it's what you're doing. It's the subject
area to which a user applies a program
and the domain evolves collaboratively.
Now this is a topic I'll come back to
again and again over the next 20 minutes
or so.
Um so I'm going to spend the first half
of this talk as I say talking about DDD
some of the principles involved in DDD
and then I'm going to move on to
hexagonal
architecture. So
um we have entities and value objects in
in DDD. Now what I'm going to do here is
I'm going to try a little
experiment. Does anybody have a£10 note
on them?
Got a hand up here. I have a£10 note on
me. Would you mind swapping your 10 note
for my 10 pound note?
Yes.
Okay. So, you can see here two10 notes,
two different£10 notes. This one here
from the gentleman. This one here was
mine. I'm going to take that and I'm
going to swap
that. Yeah. You happy with that
transaction? Yeah. I can feel a sense of
anticipation building. I can I can see
people looking. What's happening here?
It's a magic trick. It's not. Uh that
was exactly as mundane as it looked. Um
but the point is that I have a new 10
note and you have a new 10 note. But
this hasn't changed anything. These 10
notes are equal. They are different, but
they're equal. And the equality comes
from the values held within. It is 10
and it is pound sterling and that's how
we compare them. These are value
objects. Now I notice there you've got a
laptop. You know we've just established
here that um you know I like to do a
trade. I've just done a successful
trade. You've seen that partner here is
happy with the trade. Would you be
willing to swap your laptop for my
laptop? Of course not. Of course not.
And the reason for that is your laptop
has state. Your laptop has the things
that you have downloaded to it. Your
programs, your files, your emails. Mine
has state as well. It's got a picture of
a train I drew last night.
Um but the concept there is that that is
a unique laptop. It is very much your
laptop. It is individual. It's not
interchangeable. It has as a value or
sorry as an entity. It has an ID. It's
specific to you. This one has an ID. So
the differences there. Value objects are
immutable. You don't change them. You
know, we didn't upgrade this
gentleman's£10 note by changing it.
changing the picture of the queen.
Although you could do that, I wouldn't
recommend it. They don't have an
identity in this system. They're just
the equality is based on the values of
them. Whereas the entities do they
contain state the state changes over
time. They describe the current status
of the application and the equality is
based on this
identifier. I'll have you know last
night when you're all at social, I went
and bought that. That's my commitment to
a visual gag.
So let's talk a little bit about model
driven
design. Um so within the concept of um
of DDD we have
models. Models are the nouns in your
domain. models represent the things you
talk
about when you talk outside the
software, when you're talking with your
product owners, when you're talking with
your project managers, when you're
talking with your clients, whoever it is
you interact with, you talk about
things.
Um, and we want to make sure that we're
naming these things as we talk about
them outside the software, within the
software. And I'm about to, excuse me,
I'm about to come to that um in a bit
more detail later on. They should be
simple. Your models represent nouns.
They represent entities. They represent
behavior. But they also should adhere to
the single responsibility principle.
They do one thing. They know about the
relationships. If anybody was at
Marcelo's talk yesterday, he was talking
in a similar vein about models. Um
complex logic doesn't belong in there.
Um, and if you get your model correct,
it becomes trivial to enhance the
application. You don't need to complete
your model at the first pass. You just
need to know what it is, how it
interacts with certain things. And as
your domain grows, you can add new
models. You can add new relationships
with these models, but it should be
quite trivial because these things are
small and simple. So, let's look back at
the code here. We've got our club here.
We've got a golf field and we've got our
course uh which are strings. We're just
having names in these right now, but
these are things that we would talk
about outside the
um in in the real world. We would talk
about as as actual things. A field is a
thing. It's not just a string. It's not
just a
name. So, we should split that out and
represent that. We have a model now to
represent our golf field and we have a
model now to represent our course.
And then this becomes represented in our
club as well. You'll notice that the
string there has changed to the
object. Let's talk about udicus
language. What this essentially
means um and again this is another quote
from Eric Evans but what this basically
means is talk in the same language.
um be very very clear with how you're
naming things and make sure that those
names represent how people outside of
the software talk as
well. So we want to remove any
ambiguity, any names that have meaning
that could mean many things. It could
mean depending on on who's talking about
it. The language should be defined by
the domain
experts. And one thing to remember,
you're not the target audience of your
site in most cases. I know in some cases
that will be the case. But crucially use
the same language in the codes that you
use when you're planning when you use in
discussions when you use when you're
writing that language should filter
across throughout your company. The same
thing should represented everywhere. So
one example in my company that we saw um
I work in wholesale retail B2B and in
retail B2B we have the concept of
forward orders and we have the concept
of
reorders. Now a forward order is
essentially what I would think of as a
pre-order. It's something that happens
before stock is created. So the the
retailer sorry the the brand makes
available the stock says this is the
things that are coming. We've not made
any yet. We want you to place all your
orders so that we know what the demand
is so we can go and make them. And a
reorder is what I or any of you would
think of as an actual order. They come
back after that initial period and they
they order more. So to a degree they are
reordering, but if you're thinking at it
from a BTOC point of view, it's an
order. You come to the website, you have
it there, you press the stock, you go to
the order, and you place it. And we had
countless discussions internally with um
a couple of developers who were adamant
that this was an order. To them the word
reorder made no sense and in a way I can
understand that. Um it it is an order
and they were thinking purely in that B
to C term and the discussions and the
arguments we had we have to call it an
order. This is an order because it makes
sense to me. I want to call it an order.
We go back and say no, we can't call it
an order because in our domain, our
domain experts are talking about uh
reorder. We have to reflect
that. So you've heard me define the term
domain experts a couple of times here. I
want to do another little experiment
here.
Can you put up your hand if you are if
you own a company? If you run a company,
if you manage a company, can you put up
your hand as well? If you work in
product, you're a product manager,
product
owner. Can you put up your hands as
well? if you are a business
analyst.
Okay. So, if you don't have your hand up
right now, I hate to break it to you,
but you're not the domain
expert. Now, at Ray channel, uh I was
lucky enough to be involved at the very
start. I architected the system with
with help from my team. Obviously, I
have been involved in writing or
reviewing pretty much every line of
code. I understand implicitly the
relationships between all the entities
within our system. I know the
domain, but a lot of our clients are um
are brands in women's
wear. I don't understand why retail
buyers come to our system and they order
lots of this and none of this. I don't
understand when our brands are putting
together their
collections that this season everything
has to be blue and polka dots. I don't
understand why handbags cost
£500
when I paid £30 for that one and it
carries
more. I'm not the domain expert. I
understand the domain in terms of
software, but I'm not the domain expert.
So let's look back at our code
here. When I wrote this code,
um, I was thinking about it from my
point of view. A course to me is
something you go on to learn. So it
makes sense to call that thing a
course. And a golf field makes sense.
That's where you go and you go play. You
play golf on the field. So I'm going to
name these this way because that's what
makes sense to me as a developer.
Obviously, this is an awkward example
because I'm the developer and the
product owner and everything, but run
with me here. Um, so I've chosen as a
developer to name things this way
because it makes sense to me as a
developer. Now, imagine what happens
when the product owner comes to me and
says, "Okay, we need to change the cost
of the course." And I look at it and go,
okay, when you say course, do you mean
the course you mean or do you mean the
course I
mean? This should
reflect across the entire business. The
words in the software need to represent
the words outside of the
software. So I'm going to talk about
bounded context a little bit here. What
a bounded context essentially is, it's a
subdivision of your domain.
So we spoke about your domain being your
sphere of influence. It's it's
everything about your business, but you
can sometimes segregate that more. Um so
to keep the the golf analogy going,
imagine we have um a green keeper who is
responsible for maintaining the the golf
course itself. Uh we have the the club
pro who is responsible for giving the
lessons in the green keeper. They are
they have a lot of tools for example
that they would use. They're going to
have a lawn mower. They're going to have
all the uh all the tools they need to to
cut the grass to to do everything they
need to do. These things are very very
specific to that small area of the
domain. You know, the the club pro is
not going to come along and and start
using the lawnmower. Could if they
wanted to, but that is we've got this
little bounded context here that is for
them. Likewise, the pro, they're going
to have their their teaching calendar.
They're going to have
um uh a set of people they've had
lessons with before and after. They're
going to have the inventory of the club
shop. Usually, the club pro runs a club
shop. So, bounded context can have
unrelated concepts. You've got the
teaching calendar. You've got the lawn
mower on one side, but it can also share
concepts. So, think of the course, for
example. the club pro is going to go and
play on the course and the the green
keeper is going to maintain the
course. But what we've got to be wary of
is that words and phrases mean different
things in different contexts. So
just without any context whatsoever, if
I say the word ticket, what does that
mean to
you? I can guarantee there's about four
or five different things going around
the room at the moment. Everybody's got
a different thing because I've not put
any context on it
whatsoever. So, think of, and again, to
go back to our golf example, think of a
bunker. Um, to those that aren't um
proficient golfer, don't don't know that
much about golf, a bunker is basically
an obstacle on the golf course that's
filled with
sand. If you are the the club pro, the
bunker, it's it's annoying. It's it's a
thing that's there that when you're
playing golf, you sometimes land in and
you have to get out of it. It's a value
object because it doesn't matter which
bunker you're in as a pro. Just you're
in a
bunker. But if we think of it from the
point of view of the green keeper, it's
that specific bunker. It suffers with
drainage in the winter, for example, and
it tends to floods or the grass around
the lip of it is too long. to the green
keeper. These things are very specific.
So things mean different things in
different
contexts.
Okay. So
services are the actions in your
application. We spoke about the uh the
nouns before we've built our models.
Services the actions when something has
to do something.
Services cause state changes to
entities but they do not have state
themselves and we're still being driven
by the same principles that we've just
spoken about ubiquitous language and
domain
expertise. We still need to make sure
we're having that discussion when
something happens in our system. We have
a service it represents a real world
need that's spoken about. So let's look
back at our model here our
club. Um, we've got an action we want to
perform here, which is booking a tea off
time for a
user. You notice the name of that
function doesn't actually involve the
word club and it's interacting with a
number of different things. It's not
really affecting the state of the club.
It does depend on how you've modeled it.
If the model if the club has a series of
of tea off times within it, then
perhaps. But how I would prefer to look
at this is let's create a booking
service and we have a a manager for
booking tea times where we pass a user
and a club into it. Now within this
booking service which is name spaced off
we could also have a restaurant booking
manager. Uh many golf clubs have have
restaurants as part of the complex.
So continuous
integration we move into next um CI is
um was spoken about by Javi. Did anybody
go to Jav's talk yesterday? Um well he
was talking about continuous deployment.
Uh whereas I'm stopping at the first one
continuous integration
here. Your domain is constantly going to
evolve. It's going to change. is going
to shift as you move into slightly
different spheres of influence. What was
right isn't going to be right anymore.
We need to maintain discussion. We need
to maintain take that step back and
don't just furiously code. Let's take a
step back and see is this changing
anything that we used to take for
granted. Testing strategies will help
flag changes to this. If you are using
uh for example PHP spec to build your
domain and you have it making a certain
set of expectations and somebody changes
a domain your tests are going to break
and that's a good point where you can
look at it and go oh do we want to
change these break these tests at this
point is this a change we want to make
or is this an accidental
change but mainly merge code quickly and
often. If you have two teams running off
in different directions writing code,
the domain is going to shift. They're
going to make certain changes. It might
be subtle. It might be big. But if you
come six months later and try to merge
that code back in when two teams have
started going in that direction, it's
going to be hard. You should always look
to keep changes small, iterative, merge
quickly, merge often.
So these are just a few tips that I've
had from the the successful application
of DDD with the projects I've worked on.
So crucially build models as a
collaboration. This isn't
just product owner, product manager,
business analyst comes to you and says I
want this go and do it. This is a
collaborative process between both teams
to work out how to approach this. The
domain experts know how it works in the
real world. you know how it works in the
software world. Come together and work
out the best way to make that work so
that we can apply the principles we've
just spoken
about. Build your application
iteratively, small chunks. We don't need
to solve this problem. Again, Marcelo
spoke about this last night. Big design
up
front. Accept your domain will evolve
and change. You don't have to get this
absolutely spot on first
time. Have complete access to a domain
expert. This is one of the most key
things that I found in successful
projects
is when somebody who's invested in the
delivery of the project is
available 90 95% of the time it's easy
because you can ask them questions. Did
you mean this? Is this what you want?
I'm not sure what this means. Can you
clarify it for me? If you don't have
that, you're guessing. If you're
guessing, like I said before, you're not
the domain expert and you're going to
probably guess wrong. And I think Marcel
is going to kick my ass for this one.
Test, test, test. Um, if you can, so
what Marcela spoke about yesterday is
what you're not doing. You're not
testing, you're specking. And I do agree
with that. But the output of specking is
that you have a test suite. If you can
write these tests up front as you go
along, that would be brilliant because
like we just said, if you have a
breaking change and it is reflected in a
test that breaks, then that will be
flagged up very quickly and you can see
did we mean to do this? Do we want to
change the behavior of this domain or is
that accidental?
So if you take nothing else from this
talk, if there's only one tip you take,
please let it be that talk with each
other. So why are we not all doing this?
Why do we don't all just well it's it's
the
future? I use the word downside here. I
don't necessarily believe that is true.
That's why I use ish. Um but there is no
doubt it's time consuming especially
initially to set this up to start
changing your mentality to start
changing your thinking to put the
infrastructure in place to start putting
testing mechanisms in place up front to
start putting enhanced discussions
there. It's time consuming but you
notice the star there. It's timeconuming
initially but this pays itself back
manifold um towards the middle and end
of a project.
It can be confusing if you don't
understand the domain. We just spoke
about orders versus reorders versus
forward orders. If a new developer comes
into a system, you know, you've got your
language, you've got your way of
speaking, they're not going to
understand it necessarily at first. You
have to take the time to educate them,
to bring them up to speed so they
understand what you're talking
about. And there is an overhead in
maintaining constant dialogue.
A lot of your managers, your bosses will
think, okay, you're a developer, you sit
there for eight hours a day, head down,
code away. If you're having if you're
having discussions, you're not
delivering anything. Again, to me,
that's not a downside. I can see why it
could be perceived as, but having that
discussion means you're more likely to
get it right first time.
Okay, so we have now evolved our code
from the first iteration. We've got it
now nicely cut off into a domain. So I'm
going to talk a little bit about
geometry. So what are we trying to
achieve with hexagonal architecture?
There's a quote there from Alistar
Cockburn who is kind of the authority on
this. If you've not read his blog, then
it's it's the first one that comes up
when you type hexagonal architecture and
it's well worth a read. He says, "Allow
an application to be equally driven by
users programs, automated tests or batch
scripts and to be developed and tested
in isolation from its eventual runtime
devices and
databases." Obviously, what does that
actually mean? It means that if you
split your domain well enough, then
there's going to be many things in the
outside world that want to interact with
it. You're going to want to retrieve
data from multiple sources. Perhaps you
have an XML reader, you have an HTML
front end, you have an API, and you may
need to output data to multiple sources.
You could be using you could be
using Reddus, you could be using
MySQL. Doesn't matter inside your
domain. Your domain does not care. Your
domain cares about I have this object
and I want it
persisted. That's all I care
about. And this is the question that I
anticipated would come up most often
than not. The hexagon is not a hexagon
because the number six is important. It
could be pentagonal architecture,
octagonal architecture, docahedronagonal
architecture, but rather to allow people
doing the drawing to have room to insert
ports and adapters as they need, not
being constrained by a one-dimensional
layer diagram. So, traditionally, this
would be viewed left to right, top to
bottom. Um, and the hexagon just gives a
visual effect. So, this is another image
that came from Alyssa Cockburn's blog.
You can see um we speak traditionally
and again to reference Marcelo's talk
yesterday he spoke about um abstractions
deal with abstractions and push the
concretions down and away. Um if you
were at that you remember that slide top
left push the concretions down and away.
What I'm saying is basically the same
thing but I'm saying push them out and
away. Your application he uses the word
application here. This is what we've
just described as a domain sits in the
middle here and push the concretions
outside of
it. So let's look back at our
club. We're extending the OM in the club
here. This is a um the way that Kohana
uses OM to give you essentially active
records. what this
means. And I apologize for this diagram.
Um, I had a friend that helped me write
most of the slides, so they look
generally quite nice cuz he's good at
that kind of thing. I had to do this
myself. It kind of
shows. Um, but the principle of the
thing
is we want all the dependency arrows to
flow
inwards. Um, and just actually one thing
that may be slightly confusing, you'll
notice here there's two hexagons. And
you'll notice here there's two hexagons.
My outer hexagon here represents his
inner hexagon. Um, just to confuse you
even more, obviously.
Um, this isn't necessarily something
that you would need to do or want to do.
I just prefer to do it that way. I like
to split the domain models inside and
put the services wrapped around that and
then put the application layer around
about that and that's the outer hexagon
that Alistister Cogburn talks about. So
you see we've got our controllers coming
in through managers through our
services. The services bring come in
towards our um models. Everything's
great so far. That's what we want to
see. But the red arrows there, they're
coming back out now. There's kahana now
lives within our domain and is important
within our domain and we don't want that
to be the
case. So let's talk about ports. If you
noticed on the first slide um when I
mentioned hexagonal architecture, it
also said ports and adapters. Ports and
adapters is just a different term for
that. So ports are the gateways into
your domain. they define the purpose of
the
conversation. Um, so like I mentioned
before, you know, you want to store data
somewhere, but your domain doesn't care
where. So if we have another quick look
at this diagram here, the lines, the the
bold lines where it says database,
notifications, where it says user data,
where it says administration, these are
the ports in our uh application here. or
sorry that's confusing because he uses
application in our system here.
Um what the ports are for is to say okay
you can save data I'm the database port
and I will give you the contract of how
to save data but how you then use that
is up to
you. So let's illustrate that with a
little bit of
code. So I've got my club now and what
I'm building is a club repository.
The club repository is this uh contract.
Now it says if you want to persist a
club then you have to adhere to the
rules applied by this port. You can save
a club and you can find a single club by
its ID. That's all you can
do. I don't care how you do it. I don't
care where you put it. But that's the
two things you can do.
And now we look at our club. So we are
no longer using Kahano RM. So we need to
build in our constructor now which came
for free
previously. Um but nothing much more has
changed. We still got our simple club.
Um I've started name spacing a little
bit here um just to help the
illustration but it's not overly
important for this
example. Um but the important point is
we now get a constructor. build our
club, but a club doesn't know how to
save itself. Um, I missed a code I
wanted to put another slide in here that
I forgot to put in. I apologize. Uh, our
constructor, uh, sorry. Um,
originally
our No, I'm not going to go back to it.
Um, we were calling club save. The club
knew how to save itself. And this came
from the OM. And that was showed the
arrow flowing back outwards. the club
knew about application logic. Now we
don't have that. Now we pass a club into
the repository that knows how to save
itself. So we've got our ports. So the
second part of this contract is
adapters. Adapters are built on top of
the ports and they provide functionality
concretely. And you can have multiple
adapters. you probably will have
multiple
adapters. So for
example, here is a very specific
adapter. We implement the club
repository. We're using the port. We're
using that set of rules we've
defined and um through space obviously
I've commented out, but that would be
some SQL that would save a club. Some
SQL to find a club and return
it. I want to save it in
same port, same simplistic I can save
it, I can find it. And that's your your
language to um to save those to um
find one by
ID. And so a major advantage of this is
you wanted to swap your storage
mechanism out for from MySQL to
for some reason. That's how easy it is.
That slightly trivializes it obviously,
but your domain doesn't care. Your
domain doesn't
change. No behavior has changed at all
in your domain. You just build another
adapter, configure it to use that
adapter now, and you're now using
So, we've got a file system club
repository. This is how we test. We
build um we use Bhat and we use file
system. So when we configure when Bhat
spins up instead of configuring the
MySQL adapter, it configures the file
system adapter. Um it's quicker. We
don't need to go near the database when
we're running our test suite. We've just
got an adapter. Same contract. We're
still using the club repository. We
still got just our two simple
methods. And now we go back to the
controller here. So where I did have as
I just mentioned that save function now
we're passing the club into the club
repository
uh and we're saving it that way. We've
defined our
contract. So now we look a little bit
like this in the
hexagon. So these two repositories the
club repository and the tea time
repository are now the ports into our
system. Anything that wants to save
anything into a data storage has to come
through these repositories. And you'll
notice that we've got a Reddus one and a
MySQL one coming through there depending
on how we configure it, depending on
what we're running at any given
time. But you'll see the red line here,
the create club controller is still
going directly into our domain. It still
knows how to manipulate. If you go back
a slide here, we're still creating a new
club directly.
We need a port at the other side
here. So we've got a club
porter. Um I use the word porter because
it's to do with the import and export of
data in and out the system to the UI. So
it's portation. It's a porter. Um we've
defined two two rules. You can either
import a club with mixed data depending
on where it's coming from or you can
export a club which sends a club which
takes a club and exports mixed data. So
let's see a concrete realization of
that. We've got a request club porter
takes in a request builds our club from
the information
um and we can export a club by taking
the club putting the data into the
response and returning that. As I said
before that some of the code examples
are are pseudo code just for
illustration rather than than real
genuine
code. But the advantage we have here is
that same thing. We don't want to take
in a request anymore. We want to take in
JSON. We want to take in HTML. We want
to take in
XML. So let's go back to our controller.
Now all of a sudden I've got a oneline
controller.
Um, data comes in through the porter.
Data gets saved through the
repository. Domain doesn't care where
it's coming from. Domain doesn't care
where it's going
to. So, this gives us expands the
diagram a little bit here. And now we
can see the flow of arrows is all coming
in. the the users, the clubs, the
models, they don't care where the data
is coming from. They don't care how
they're made. They don't care anything.
The services don't care where the data
comes from. They know what they have to
do. And the concrete implementations are
based on
configuration. So, what sort of ports
should there be? Um, traditionally in a
web application, you're not going to
need that many. Alistister Cockburn when
he originally wrote his slides he was
dealing in enterprise software big big
behemoth systems and he said he'd never
seen more than four um traditionally as
I say in a web app you're not going to
see much more than than a couple data
comes in and out to screen to UI data
gets persisted into a database
um you could maybe have logging ports
notification ports if you needed
that But
um the hexagon as I say is not you don't
need to have six ports. There aren't six
defined ports. It's just an illustration
of a number of
ports.
Okay. Thank you for your time.
[Applause]
Like I say, if um if you do have any
further questions on this and you do
want to try and contact me and you don't
get a chance to see me today, then
please feel free to contact me through
those
um places.
And that's a reference to the book that
Eric Evans wrote. The second link is a
um it's a PDF that summarizes the book.
Um I built a lot of the first part of
the the talk on that and that's uh also
Cobburn's blog on hexagonal architecture
is worth reading as well.
Yeah, if there's any
questions there
I go first. Yeah.
Okay. So am I going first or? Yeah, go
ahead. Okay, Gordon, what would you
suggest for a team uh so if your team
leading a team and some of the people in
the team still not up to speed with DDD,
how do you recommend the team lead to
kind of u bring them up to speed, what
what kind of things did you Well, the
main thing I would suggest um did
everybody hear the question? Okay, it's
how to introduce new team members to TDD
or to DDD. The main thing is as I say
like the main point I put across it's
communication. Take the time. Um the
domain language you use is going to
become second nature to you. You're
going to refer to things without
thinking about it. So it just it's a
slow process. You have
to go through with them. You have to
make sure they're involved in a lot of
meetings with you. So don't split out
the meetings into well these two guys
know about this so they're going to sit
and have this discussion and nobody else
is going to know. Try and involve as
many people as you can in those
discussions when you're talking about
domain objects when you're talking about
models uh when you're talking about
behaviors of the domain so that it
becomes second nature to people over
time that they'll start picking it up.
Uh in terms of the techniques you can
use certain things you can use pairing
with more senior developers who do
understand it. um code reviews um
helping pick out uh maybe places they've
gone wrong sit with them help them
understand okay I see what you were
trying to do there but maybe you know we
try to approach a problem this way help
them understand why to do that um but
it's just continuously working with them
um and investing that time uh like I
said there's there is some overheads and
this is an overhead that's worth it
invest the time team lead may have to
take a cut in how they can actually
deliver during that. They're maybe not
doing so much programming during that
time, but if they invest the time, then
the team as a whole grows through that.
Does that help?
Hi. Um could you come back to your
hexagonal row? This one here.
Yeah. Um my question is uh if you talk
about um um your code
domain so why the the service is out of
this domain of this core sorry they are
not. So this was what I spoke about when
I said it was maybe slightly confusing
between the two um diagrams. My core
domain here is the outer hexagon and I
split the inner hexagon to be the domain
models
but the outer hexagon is domain. So the
domain still contains the services but
if if you you could go to the controller
please. One second.
Sorry. Yeah.
Yeah. You you're calling here direct to
the
repository and um I don't know why
you're doing this instead of uh calling
from your service that it's from your
domain. I mean if you have the interface
you only need the the implementation in
the controller. Yes. Um absolutely right
and this is a conversation I had about
half an hour ago before I started
myself. Um you would perhaps want to so
what I'm trying to illustrate mainly
here is the the data comes in in a
format. it comes through a porter which
is defined by the port and it's now in
your domain and it goes out through a
repository
um through a specific one. So that's the
layer I'm trying to enhance uh to show
here. Um I'm using a controller as um
because we're you it's we're generally
web developers here so we do use
controllers but what you might want to
do is abstract that knowledge into the
domain as well. have a service that
deals with um converting the data from
the controller into the format that your
uh concrete adapter would then use in
the domain in that model. Um so yes,
perhaps that's maybe not clear. And the
other thing that um to follow up on the
point you just mentioned there that I
was um thinking is that the controller
here points at the porter, but if you
actually look at the code, it also comes
around the other side and points at the
repository as well.
So the controller itself doesn't quite
fit this model. Um I I tried to draw it
in here just for illustration that um
it's there. What you would maybe want to
do is have another service like you say
inside the domain that um that takes
that converts the data through the
controller. We would use a param
converter for example to do that um and
uh use that uh that process.
Okay. Does that make sense? Yeah. Yeah.
the controller the controller doesn't
quite fit the model. I agree with what
you're saying there. The important part
I was trying to illustrate was data's
coming in in one format. You use a
concrete um implementation of a port to
get it into your domain.
Thank you.
One over here. One over there.
Yeah. Good.
Hi um thanks for the talk. Um I was
wondering I work in a large organization
with different teams in you know in
different countries for example so the
bounded context stuff is quite
interesting. Have you got any advice on
on how that scales and what are the
artifacts and agreements that you you
end up with?
Um not great advice because I work in a
startup. I work in a very small um code
base. Uh how I would have approach or
how I approached that within our system
is through name spacing.
Um
and so you you split it out that way.
But it's not a problem to be honest that
I've solved myself. Um because generally
speaking, a lot of the um code bases I
work with are quite small. They are
quite contained. They're not as
sprawling unfortunately. So I don't have
that much advice I could give you there.
Um okay I have one other question. Um
we've used a lot of terms like value
objects, models, services and then
overlapping that with standard MVC um
web frameworks. So could you give like a
a summary of of how these things map or
or where they don't map well?
Uh that would be a talk in itself I
think um to do it properly. But um like
I said at the start uh in terms of OO um
design most of us are relatively okay
with that. You know your models map to
your objects. Um so the concepts do
cross over in terms of MVC. You're
seeing we're still using uh a
controller. The model becomes the domain
really. You're working with the full
domain even if you're only using parts
of it. the view is is coming through the
port. So you are you're using your
porter to export data. You might have an
HTML porter that ports to that. Um you
might use an API to export the
information out that a front end can
then consume. Um so the V is almost
irrelevant in MVC. Um with this
hexagonal architecture you just you
output uh your models in AI and how the
the front end would then consume that is
up to
it. Um in terms of O like I say much of
the much of the structure is the same.
You have objects that interact with each
other. The principles of keep your
objects small still apply. The
principles of dealing with abstractions
encapsulation they all still apply. So
there's
nothing there's not a huge shift in
mentality required to start thinking in
terms of DDD. The biggest shift is the
conversational aspect of it and
understanding that
um there are people employed in your
organization who do know the domain
better than you. So let them help you.
But for example um you know in your
diagram um which ones are the services
which ones are the entities where are
the models in in that what I've tried to
do with this uh diagram if you can bring
it back up onto the screen
please is the color code here. So the
inner hexagon are my models. Those are
the simple objects. There's club there's
course they can interact with each
other. The club knows about the course.
The second layer uh color coded in
green, these are our services that
interact directly with our models. But
you notice that our models don't
interact backwards with the services.
And then external to the hexagon. So
this goes into our application layer um
start dealing with the services
themselves.
That's helpful. Thank you. Yeah. Hi
there. Um great talk. Um interested when
you're talking about the uh naming and
say um later down the line the domain
experts realize they've made a mistake
and a user should be called a player.
Would you go to the extent of renaming
all the users in the code to to players?
Ideally yes I would. Um but there has to
be a time and place for it.
Um I'm not generally a fan of
refactoring for refactoring state
stopping and um you know just having
we're just going to do code now. Um I do
believe in always moving the business
objective forward. So at a point where
it made sense to do that I would do it
but the short answer is yes I would
advocate doing that.
Um one more about naming which seems to
be uh very important. Um if you're
coming from a design pattern backgrounds
uh you will most likely use a lot of
names like this is something factory or
observer or anything. What is conflict
with using uh domain based naming or do
they work together because they don't
apply to actually the same entities? I
believe that you can um and you'll
notice I use the word collaboratively
quite often. Um it's not necessarily the
fact that you have to adhere to what
your domain expert says because you know
you guys are the technical experts and
there is a a middle ground. You should
always try as much as you can to to name
things as people as things are going to
be named but it might not always be
possible. There might be ways of naming
things. You might call something for
example a factory or an observer. That's
perfectly okay as long as there's still
a description that maps to the outside
world.
Hi there. Do you have any advice for
structuring the um application? Do you
have like a a domain uh a namespace for
your models and your services or do you
mix them together?
How I tend to do it is at the the root
source folder. Um I would have name
spaces for each of my domain models. So
a user um I would have a club course
would maybe live within club. Um the the
services live at that level as well. But
you'll notice if I go back
um I use the word service there. The
services live within there but they live
at the same level. Uh like I say this is
personal preference. I'm not saying that
this is necessarily right or wrong.
Um and then we have a folder as well at
that level called infrastructure and our
doctrine uh lives in there or symfony
lives in there. All our controllers live
in there that um are essentially outside
our domain. So the three layers live at
the same layer within the code. Um you
could what I have done in the past is
split out the model layer into its own
um subdomain as well. So you have model
slash user slash user model
clubcourse. Um it's partially down to
personal preference I think but as long
as there is a clear distinction to you
and it makes obvious to you and your
team um then I think there are there are
ways to do it that suit that suit you
that's just how we choose to do it.
Thank you.
Any more questions?
Okay, thank you everyone.
[Music]
I don't
think I
want I want
