Skip to content

Instantly share code, notes, and snippets.

@sroccaserra
Last active July 21, 2021 08:17
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sroccaserra/d37aa6538696b5d94369ab13fbe3e63b to your computer and use it in GitHub Desktop.
Save sroccaserra/d37aa6538696b5d94369ab13fbe3e63b to your computer and use it in GitHub Desktop.
Alistair in the 'hexagone'

Alistair in the 'hexagone'

2017-06-20

My notes from Alistair in the 'hexagone', a cross-over meetup event mixing:

With @TotherAlistair and @tpierrain.

See also the videos of the event:

Note: you can find the paper board drawings made during this presentation here, thanks to @PatrickGIRY. It helps to vizualize "things on the left" and "things on the right" :)

Introduction

"More hits on my 2004 Hexagonal Architecture article than in all my use case articles, it happened over the last two years."

"Early 1990's Kent Beck style programming."

"A Port is just an interface. OK, you can go home."

The Hexagon

What is a pattern? "Patterns of X" = "Common characteristics of good examples of X."

Configurable dependency (Gerard Meszaros): general name to replace "Dependency Injection" and Inversion of Control, the former a specific implementation, the latter a double negative.

Things on the left, things on the right

The hexagon is at the center. The business code is inside the hexagon. Then, outside of the hexagon, there is a left-hand side and a right-hand side.

The things on the left we call drivers, that drives the system around. On the left, I don't care if it's a person or a computer (draws a stick figure with a square head to illustrate).

The things on the right are of two kinds, repositories or recipients.

Hexagon has configurable dependencies on the right-hand side and the left-hand side.

Ports

A Port is the intention of the dialog, no notion of technology. You say what it's for. "This is for ...ing".

"This interface is for adding events". "This is for showing images".

"For Selecting a drink" "For Obtaining prices & recipes" "For dispensing"

Primary actor, secondary actor

The primary actor : the one who does the triggering (on the left-hand side)

The secondary actor : the one triggered (on the right-hand side).

Why a hexagon

Why is it a hexagon? I didn't want a square because people focus on top, bottom, left, right. Then pentagon was too complicated to draw. The hexagon was the smallest polygon that was not taken that I could draw.

Kata

Code a program that give some poems.

Plan:

  • One port "for requesting poems" (left side).
  • One port "for obtaining poems" (right side).
  • First adapter: the test case. The test case is a legitimate driver with a legitimate adapter. The test case is the first user!
  • The first repository is a stub. At that moment, the hexagon is complete. The hexagonal architecture is in place, with very few lines of code. See how simple it is!
  • Then a console adapter on the left working with the stub
  • Then a file adapter on the right.

Implement only one verb, "GiveMeSomePoetry()".

In TDD.


To enter the hexagon, we need a left-hand side port:

    // IRequestVerses: left-hand side port
    // PoetryReader: the hexagon
    IRequestVerses poetryReader = new PoetryReader();
    var verses = poetryReader.GiveMeSomePoetry();

Note: for an interface, you can have multiple verbs that will be part of the interface.

Then add a right-hand side port:

    // IObtainPoems: right-hand side port
    IObtainPoems poetryLibrary = Substitute.For<IObtainPoems>();
    poetryLibrary.GetMeAPoem().Returns("If you could read a leaf or tree..."); // don't use the same poem to easily tell if something is broken

    var poetryReader = new PoetryReader(poetryLibrary);
    var verse = poetryReader.GiveMeSomePoetry()

Note: after that, we can refactor the first test (that tests left-hand side) to use a HardCodedLibrary (that implements the IObtainPoems interface).

    var hardCodedLibrary = new HardCodedLibrary();
    IRequestVerses poetryReader = new PoetryReader(hardCodedLibrary);
    var verses = poetryReader.GiveMeSomePoetry();

The hexagon is complete. We have something really small that has the shape we want. Now we can make it grow keeping the shape.


Note: then see 3 steps initialization in the slides (pdf). Instantiate the right-side adapters, then the hexagon, then the left-side adapters.

For the rest of the kata, see:

When you implement adapters, map from infra to domain, use domain, then map back from domain to infra.

Note: the ports are inside the hexagon. The adapters are outside (in the infrastructure directory, that can be structured if there are many adapters).

Questions

There's only inside and outside.

Hexagonal architecture + CQRS? Example by Pat Maddox. Different, the read / write split: no more a single hexagon, or a hexagon only on the write side. The business logic is on the write side.

Out of the tar pit (pdf) - Tar pit architecture?

Bonus

Bonus from Twitter discussions in the following days after the event.

@totheralistair

https://twitter.com/TotherAlistair/status/877831204376113152.

  1. most ppl focus on left side. I got hurt more by right side absence (I talk about HA for pain from previous experiences more than futures)

1a. microservices is a left-side conversation, CQRS is a right-side (not write-side gah) conversation

1b. in 1994, I had trouble getting ppl to see batch jobs are legit drivers (think use cases as project contract, 1e actors are batch jobs)

1c. 1997, CORBA ~~ micro services. The cost of sending requests out through CORBA was too expensive. I think on-chip vs off-chip signals

1d. 2000 SOA == same same, same ideas, same problems

1e. 2002 Mho's weather warning system needs hook 2 apps together. He doesn't say SOA or micro services, just names need To me, same as batch

1f. 2014 microservices: yawn, same same My only Q: has it become cheap enough to send signals out of the app to make it worth it? u tell me

1g. I'm getting ancient, seen this all 5 times now all only about putting an API on the left side how 1975 tell me what's new

https://twitter.com/TotherAlistair/status/877845075966935040

2a. CQRS is a right-side - recipient, not repository - conversation. The event store is a simple right-side recipient of the app @gregyoung

2b. That the event store is a hexagon is a bit of a yawn, but probably ppl violate that anyway as they tend to do

2c. the two um hexagons together do not look like just a bigger hexagon to me they look like two systems operating in tandem

2d. glued together at the relevant primary actor's terminal. wd need to see an implementation to be convinced it's 1 hexagon Greg?

Also: Mountain West Rubyconf 2010 - Alistair Cockburn - CQRS

@gregyoung

https://twitter.com/gregyoung/status/10288731558

@totheralistair I am thiking more that hexagonal applies to the write side but not the read... A good Sunday night beer conv

@tpierrain

Same thing applies to the domain logic

@mathiasverraes

https://twitter.com/mathiasverraes/status/877493260381548544

That's how I've been doing it

@totheralistair I am thiking more that hexagonal applies to the write side but not the read... A good Sunday night beer conv

@PatrickLouys

@mathiasverraes how do you architect the read side? Interface in application layer and implementation in infrastructure?

@mathiasverraes

Most of the time: a single class that listens to events, writes state changes directly to db, responds to queries. No need for domain model.

Design them around queries, answering those is the primary purpose. Events and state are simply means to answer queries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment