6 Comments
User's avatar
Valentina Jemuović's avatar

What approach do you use when a team is stuck in using ORMs and shows resistance towards moving away from ORMs?

Expand full comment
Oliver Zihler's avatar

The question I would always consider first is "is there a problem atm?". Hexagonal architecture does not come for free. Especially if we use ORMs and not directly query the database, we will have to map the database entities (or db rows as classes if we consider a SQL db) to corresponding core objects. This apparent "duplication" of data fields is what I see as the biggest driver of resistance. So coming back to the question of "is there a problem atm?", we need to consider the use cases the application provides. Are there lots of simple queries that rely on only little business logic? Then we may be just fine with an ORM (or we could even strip away any abstraction and directly query the DB). On the other hand, do we have lots of commands with intricate business logic that is scattered around badly designed abstractions and services (Of course, it may also be the other way round, that we have lots of business logic on the query side and only little on the command side)? In that case, what we often end up doing is moving domain logic into these database entities, which in turn tangles up database-specific fields and logic with domain fields and logic. I have seen classes exceeding 2000 lines of code as they grow over time, entangling data access and business logic and sometimes even presentation logic all in one DB entity. So in my experience, lowering the resistance to Hexagonal Architecture means highlighting the pain the current solution with ORMs is causing while emphasising the benefits HA can bring in that regard. But then, I would also not directly jump to the entirety of HA and just present it as the silver bullet solution. Instead, the important part is to realise that there are actually around 3-4 types of concerns in any business application: presentation, business (application & domain), and data access. A team can profit from learning to separate these types of concerns first before moving to HA. Separating a use case into these concerns highlights the need to have independent objects that handle data access or business rules. How can we separate these two concerns? By introducing an adapter between business rules and data access. This means that the database entity should only handle data access concerns, while the corresponding domain object should only handle business concerns. Only one rule needs to be followed then: the adapter will only accept domain objects or simple data POxO records (x meaning whatever OO language is used) in their interfaces. No data access may pass the adapter's borders. From there on, introducing ports to segregate adapter interfaces becomes trivial and may not even be required. Especially if the team is reluctant, the fewer concepts introduced, the better. Additionally, introducing one concept iteratively only when there is a need for it may increase acceptance. I think we should be thinking about the long game here - transforming a code base step by step by using the most beneficial concepts first (e.g. dependency inversion through adapters), while not overloading teams with too many details that may increase the possibility to reject the entirety of the concept (i.e. HA). So, in short, I'd highlight and focus on iteratively introducing beneficial concepts that alleviate the biggest pain points, typically without even mentioning that what I am doing is moving towards HA or CA or VSA, etc.. Using such terms can seem dogmatic and increase the resistance, so it's better to avoid them altogether.

Expand full comment
Ray Sinnema's avatar

Great answer. I also found that a mapping library like MapStruct can reduce the boilerplate that feeds resistance.

Expand full comment
Oliver Zihler's avatar

I agree, Ray. Any measure that reduces the number of manual mappings and thus helps to diminish a team’s barrier to adopting Hexagonal Architecture, are highly beneficial.

Expand full comment
Abel Miraval's avatar

Hi where can I find a template with clean architecture for my project, I have seen that several authors, bloggers structure the project in different ways, with different libraries that can be overwhelming to try to find the perfect point to want to improve the code... long live the code

Expand full comment
Oliver Zihler's avatar

Hey Adel! What do you exactly mean by "different libraries"? The basic structure follows always the Hexagonal idea of having an "outside" and an "inside". The inside in Clean Architecture are the use cases, inbound/outbound ports, and entities, and the outside the adapters, frameworks, etc. I am about to write an article on different structures and as soon as I cover how to get from hexagonal to clean architecture. The main folders you probably find in any Clean Architecture are along the lines of:

adapter

application

|_use_cases

|_ports

entities

If DDD is added on top, then "entities" becomes "domain" (like in Vaughn Vernon's Implementing DDD). Adapters can also be called "outside", while application and entities may be summarised in a folder as "inside" or "core", depending on how much of Hexagonal Architecture's nomenclature is used.

Ports (and sometimes also adapters) may be structured in "in/inbound" and "out/outbound", and if we take Clean Architecture's nomenclature we'd have "controller", "gateway", and "presenter" adapters.

Additionally, I would structure each Hexagon/Clean Arch within either a bounded context (use cases that belong together) or even vertical slices, where each use case of clean architecture is within an own folder with a use case specific name.

The issue I see is that there is no one prescription and for each application / use case you need to think about which folders make sense and which don't.

If you want a rather simple example of how I sometimes structure it, check out the following repository we used in a tech excellence talk:

https://github.com/ozihler/techexcellence-eventstorming-cleanarchitecture/tree/master/src/main/java/org/oliverzihler/techexcellence/mydancingevent

Let me know if I misunderstood you or if you have other questions! :)

Olly

Expand full comment