-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for Hexagonal Architecture #71
Add support for Hexagonal Architecture #71
Conversation
Any feedback @StephanPirnbaum ? |
Sorry for taking so long. There was a lot to finish for this year. Looks good to me. Let's ping if they have any objections and if not, we merge it. Thanks for your contribution! |
Maybe a thought: The hexagon annotations are now in the onion package and module. Although highly related, I don't know if this might be confusing for the end user. |
I think this definitely needs some preliminary discussion. The terminology seems not to be very well-grounded, meaning that different resources use different terms, and I had a hard time finding canonical references for them. The source closest to Alistair I could find was this one: https://web.archive.org/web/20060711221010/http://alistair.cockburn.us:80/index.php/Hexagonal_architecture The problem of naming becomes particularly apparent in the I generally wonder whether we should do this at all because P&A is pretty much identical to the simplified flavor of Onion Architecture we already have in place. There's value in distinguishing between input and output ports, although things can get messy here, too: is a connector to a broker both sending and receiving messages and input or output port? Trying to arrange them by package would force that integration to be split up among packages, wouldn't it? |
Thanks for your feedback.
Definitely, that's why I started #70
I agree, multiple terms waft around hexagonal architecture. (Basic Port, Adapter + some attempts to be more specific). Nevertheless, I see multiple teams going to hexagonal architecture but due to lack of uniquely defined standard terms, the mess begins. Actually, that was one of the motivations to deal with that topic.
I agree 100%.
IMHO hexagonal as well as clean architecture are kind of onionish, similar ideas but different in wording and details. Stating a clear taxonomy would be a goal as well.
To address your particular example, I would consider a message listener as input port and message producer as output port for the logically same broker. In essence, I see a general need for clarification about this topic among developers and jmolecules could give guidance here. Concrete open topics are:
Should we continue in #70 ? |
I gave some input in #70 (comment) |
I took the contribution here and pushed a polished up variant of this to
It seems generally ready for merge and thus inclusion into 1.5. I'd just need a real name or alias to be used in the |
An annotation like public static ArchRule ensureHexagon() {
return hexagonArchitecture()
.whereLayer(PRIMARY_ADAPTERS)
.mayNotBeAccessedByAnyLayer()
.whereLayer(SECONDARY_ADAPTERS)
.mayNotBeAccessedByAnyLayer()
.whereLayer(APPLICATION_CORE)
.mayOnlyBeAccessedByLayers(PRIMARY_ADAPTERS, SECONDARY_ADAPTERS);
}
private static LayeredArchitecture hexagonArchitecture() {
return Architectures.layeredArchitecture()
.layer(APPLICATION_CORE).definedBy(layerType(ApplicationCore.class))
.layer(PRIMARY_ADAPTERS).definedBy(layerType(PrimaryAdapters.class))
.layer(SECONDARY_ADAPTERS).definedBy(layerType(SecondaryAdapters.class));
} The input-/output-naming for the ports is a bit odd. Would an application fetch data from an external system or a database by means of an |
I am not sure I can follow. The primary concepts of this architectural approach are ports and adapters. Defining constraints for those without referring to those (esp. the ports) doesn't seem appropriate. I guess adapters can be defined to only refer to ports. Primary ones in terms of dependencies, secondary ones in terms of implementation. I guess we could introduce meta-annotations |
Concerning the constraints: How can I formulate a constraint that elements from the "core" may not depend on any adapter? Isolating the core from delivery mechanisms and technology - which belong in the realm of adapters - is one of the goals of hexagon architecture. Concerning the naming of the port annotations: Primary actor (outside SUD) -> primary adapter -> primary port -> application |
First: great input! I like where this is going.
That depends on the implementation of the validation. One could argue (and thus implement the validation that way) that all types referred to by a type annotated with The ability to annotate packages is primarily for consistency reasons with other architecture annotations. Personally, I am not the greatest fan of that pattern as it create incentives to structure packages around technical abstractions, which usually leads to package arrangements driven by organization not for encapsulation. That said, I can imagine an arrangement that declares adapter packages but a single package with
Any other technical arrangements like frameworks out of the picture, no code, maybe except other adapters must depend on adapters. Alistair uses the term
We should move to the "primary" / "secondary" terminology for the ports, too, then. I like how it takes the terminology away from data flow. |
A single port package becomes essentially a port layer separating adapters from the application core. A valid approach and one that is useful when core components share ports. Another approach would be to structure the application core into business-oriented slices, each bringing their own ports with them. This works in practice quite well in conjunction with the moduliths extension for spring boot. Each module is either a primary/secondary adapter or an application core module. I like the fact that there is still room for design choices within the archtitecture. |
Yeah, I just wanted to get across that especially secondary port package bear the risk of code being able to bypass primary ones as all types need to be public in them so that the application code can refer to them. That unfortunately opens them up for reference unless. As you indicated, it'd work fine in a Moduliths arrangement, though. |
Big thank you for the progress on this topic 👍 Regarding
I would not mind if you leave me out. I mean, almost everything came from you guys. |
Fine with me. You took the time to initiate the discussion and first draft and that kind of contribution should be visible. It is still through this discussion here, so I'll proceed without you being mentioned as author in the source files as you suggested. |
Move hexagonal architecture abstractions into separate JAR. Also remove the @corelogic annotation in favor of @Application. Revamped the Javadoc and added a bit more metadata. Introduces @adapter and @PORT annotations for use as meta-annotations primarily.
This is in place now feel free to give the snapshots a try. I wouldn't mind seeing a PR implementing the corresponding violation checks using ArchUnit in xmolecules/jmolecules-integrations. 🙃 |
I've just created #79 for additional metadata in the annotations to support extracting developer documentation. |
taken from https://medium.com/idealo-tech-blog/hexagonal-ports-adapters-architecture-e3617bcf00a0